sdk_library.go 114 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126
  1. // Copyright 2018 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package java
  15. import (
  16. "fmt"
  17. "path"
  18. "path/filepath"
  19. "reflect"
  20. "regexp"
  21. "sort"
  22. "strings"
  23. "sync"
  24. "github.com/google/blueprint"
  25. "github.com/google/blueprint/proptools"
  26. "android/soong/android"
  27. "android/soong/dexpreopt"
  28. )
  29. const (
  30. sdkXmlFileSuffix = ".xml"
  31. )
  32. // A tag to associated a dependency with a specific api scope.
  33. type scopeDependencyTag struct {
  34. blueprint.BaseDependencyTag
  35. name string
  36. apiScope *apiScope
  37. // Function for extracting appropriate path information from the dependency.
  38. depInfoExtractor func(paths *scopePaths, ctx android.ModuleContext, dep android.Module) error
  39. }
  40. // Extract tag specific information from the dependency.
  41. func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) {
  42. err := tag.depInfoExtractor(paths, ctx, dep)
  43. if err != nil {
  44. ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error())
  45. }
  46. }
  47. var _ android.ReplaceSourceWithPrebuilt = (*scopeDependencyTag)(nil)
  48. func (tag scopeDependencyTag) ReplaceSourceWithPrebuilt() bool {
  49. return false
  50. }
  51. // Provides information about an api scope, e.g. public, system, test.
  52. type apiScope struct {
  53. // The name of the api scope, e.g. public, system, test
  54. name string
  55. // The api scope that this scope extends.
  56. //
  57. // This organizes the scopes into an extension hierarchy.
  58. //
  59. // If set this means that the API provided by this scope includes the API provided by the scope
  60. // set in this field.
  61. extends *apiScope
  62. // The next api scope that a library that uses this scope can access.
  63. //
  64. // This organizes the scopes into an access hierarchy.
  65. //
  66. // If set this means that a library that can access this API can also access the API provided by
  67. // the scope set in this field.
  68. //
  69. // A module that sets sdk_version: "<scope>_current" should have access to the <scope> API of
  70. // every java_sdk_library that it depends on. If the library does not provide an API for <scope>
  71. // then it will traverse up this access hierarchy to find an API that it does provide.
  72. //
  73. // If this is not set then it defaults to the scope set in extends.
  74. canAccess *apiScope
  75. // The legacy enabled status for a specific scope can be dependent on other
  76. // properties that have been specified on the library so it is provided by
  77. // a function that can determine the status by examining those properties.
  78. legacyEnabledStatus func(module *SdkLibrary) bool
  79. // The default enabled status for non-legacy behavior, which is triggered by
  80. // explicitly enabling at least one api scope.
  81. defaultEnabledStatus bool
  82. // Gets a pointer to the scope specific properties.
  83. scopeSpecificProperties func(module *SdkLibrary) *ApiScopeProperties
  84. // The name of the field in the dynamically created structure.
  85. fieldName string
  86. // The name of the property in the java_sdk_library_import
  87. propertyName string
  88. // The tag to use to depend on the stubs library module.
  89. stubsTag scopeDependencyTag
  90. // The tag to use to depend on the stubs source module (if separate from the API module).
  91. stubsSourceTag scopeDependencyTag
  92. // The tag to use to depend on the API file generating module (if separate from the stubs source module).
  93. apiFileTag scopeDependencyTag
  94. // The tag to use to depend on the stubs source and API module.
  95. stubsSourceAndApiTag scopeDependencyTag
  96. // The tag to use to depend on the module that provides the latest version of the API .txt file.
  97. latestApiModuleTag scopeDependencyTag
  98. // The tag to use to depend on the module that provides the latest version of the API removed.txt
  99. // file.
  100. latestRemovedApiModuleTag scopeDependencyTag
  101. // The scope specific prefix to add to the api file base of "current.txt" or "removed.txt".
  102. apiFilePrefix string
  103. // The scope specific suffix to add to the sdk library module name to construct a scope specific
  104. // module name.
  105. moduleSuffix string
  106. // SDK version that the stubs library is built against. Note that this is always
  107. // *current. Older stubs library built with a numbered SDK version is created from
  108. // the prebuilt jar.
  109. sdkVersion string
  110. // The annotation that identifies this API level, empty for the public API scope.
  111. annotation string
  112. // Extra arguments to pass to droidstubs for this scope.
  113. //
  114. // This is not used directly but is used to construct the droidstubsArgs.
  115. extraArgs []string
  116. // The args that must be passed to droidstubs to generate the API and stubs source
  117. // for this scope, constructed dynamically by initApiScope().
  118. //
  119. // The API only includes the additional members that this scope adds over the scope
  120. // that it extends.
  121. //
  122. // The stubs source must include the definitions of everything that is in this
  123. // api scope and all the scopes that this one extends.
  124. droidstubsArgs []string
  125. // Whether the api scope can be treated as unstable, and should skip compat checks.
  126. unstable bool
  127. }
  128. // Initialize a scope, creating and adding appropriate dependency tags
  129. func initApiScope(scope *apiScope) *apiScope {
  130. name := scope.name
  131. scopeByName[name] = scope
  132. allScopeNames = append(allScopeNames, name)
  133. scope.propertyName = strings.ReplaceAll(name, "-", "_")
  134. scope.fieldName = proptools.FieldNameForProperty(scope.propertyName)
  135. scope.stubsTag = scopeDependencyTag{
  136. name: name + "-stubs",
  137. apiScope: scope,
  138. depInfoExtractor: (*scopePaths).extractStubsLibraryInfoFromDependency,
  139. }
  140. scope.stubsSourceTag = scopeDependencyTag{
  141. name: name + "-stubs-source",
  142. apiScope: scope,
  143. depInfoExtractor: (*scopePaths).extractStubsSourceInfoFromDep,
  144. }
  145. scope.apiFileTag = scopeDependencyTag{
  146. name: name + "-api",
  147. apiScope: scope,
  148. depInfoExtractor: (*scopePaths).extractApiInfoFromDep,
  149. }
  150. scope.stubsSourceAndApiTag = scopeDependencyTag{
  151. name: name + "-stubs-source-and-api",
  152. apiScope: scope,
  153. depInfoExtractor: (*scopePaths).extractStubsSourceAndApiInfoFromApiStubsProvider,
  154. }
  155. scope.latestApiModuleTag = scopeDependencyTag{
  156. name: name + "-latest-api",
  157. apiScope: scope,
  158. depInfoExtractor: (*scopePaths).extractLatestApiPath,
  159. }
  160. scope.latestRemovedApiModuleTag = scopeDependencyTag{
  161. name: name + "-latest-removed-api",
  162. apiScope: scope,
  163. depInfoExtractor: (*scopePaths).extractLatestRemovedApiPath,
  164. }
  165. // To get the args needed to generate the stubs source append all the args from
  166. // this scope and all the scopes it extends as each set of args adds additional
  167. // members to the stubs.
  168. var scopeSpecificArgs []string
  169. if scope.annotation != "" {
  170. scopeSpecificArgs = []string{"--show-annotation", scope.annotation}
  171. }
  172. for s := scope; s != nil; s = s.extends {
  173. scopeSpecificArgs = append(scopeSpecificArgs, s.extraArgs...)
  174. // Ensure that the generated stubs includes all the API elements from the API scope
  175. // that this scope extends.
  176. if s != scope && s.annotation != "" {
  177. scopeSpecificArgs = append(scopeSpecificArgs, "--show-for-stub-purposes-annotation", s.annotation)
  178. }
  179. }
  180. // By default, a library that can access a scope can also access the scope it extends.
  181. if scope.canAccess == nil {
  182. scope.canAccess = scope.extends
  183. }
  184. // Escape any special characters in the arguments. This is needed because droidstubs
  185. // passes these directly to the shell command.
  186. scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs)
  187. return scope
  188. }
  189. func (scope *apiScope) stubsLibraryModuleNameSuffix() string {
  190. return ".stubs" + scope.moduleSuffix
  191. }
  192. func (scope *apiScope) stubsLibraryModuleName(baseName string) string {
  193. return baseName + scope.stubsLibraryModuleNameSuffix()
  194. }
  195. func (scope *apiScope) stubsSourceModuleName(baseName string) string {
  196. return baseName + ".stubs.source" + scope.moduleSuffix
  197. }
  198. func (scope *apiScope) apiModuleName(baseName string) string {
  199. return baseName + ".api" + scope.moduleSuffix
  200. }
  201. func (scope *apiScope) String() string {
  202. return scope.name
  203. }
  204. // snapshotRelativeDir returns the snapshot directory into which the files related to scopes will
  205. // be stored.
  206. func (scope *apiScope) snapshotRelativeDir() string {
  207. return filepath.Join("sdk_library", scope.name)
  208. }
  209. // snapshotRelativeCurrentApiTxtPath returns the snapshot path to the API .txt file for the named
  210. // library.
  211. func (scope *apiScope) snapshotRelativeCurrentApiTxtPath(name string) string {
  212. return filepath.Join(scope.snapshotRelativeDir(), name+".txt")
  213. }
  214. // snapshotRelativeRemovedApiTxtPath returns the snapshot path to the removed API .txt file for the
  215. // named library.
  216. func (scope *apiScope) snapshotRelativeRemovedApiTxtPath(name string) string {
  217. return filepath.Join(scope.snapshotRelativeDir(), name+"-removed.txt")
  218. }
  219. type apiScopes []*apiScope
  220. func (scopes apiScopes) Strings(accessor func(*apiScope) string) []string {
  221. var list []string
  222. for _, scope := range scopes {
  223. list = append(list, accessor(scope))
  224. }
  225. return list
  226. }
  227. var (
  228. scopeByName = make(map[string]*apiScope)
  229. allScopeNames []string
  230. apiScopePublic = initApiScope(&apiScope{
  231. name: "public",
  232. // Public scope is enabled by default for both legacy and non-legacy modes.
  233. legacyEnabledStatus: func(module *SdkLibrary) bool {
  234. return true
  235. },
  236. defaultEnabledStatus: true,
  237. scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
  238. return &module.sdkLibraryProperties.Public
  239. },
  240. sdkVersion: "current",
  241. })
  242. apiScopeSystem = initApiScope(&apiScope{
  243. name: "system",
  244. extends: apiScopePublic,
  245. legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
  246. scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
  247. return &module.sdkLibraryProperties.System
  248. },
  249. apiFilePrefix: "system-",
  250. moduleSuffix: ".system",
  251. sdkVersion: "system_current",
  252. annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS)",
  253. })
  254. apiScopeTest = initApiScope(&apiScope{
  255. name: "test",
  256. extends: apiScopeSystem,
  257. legacyEnabledStatus: (*SdkLibrary).generateTestAndSystemScopesByDefault,
  258. scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
  259. return &module.sdkLibraryProperties.Test
  260. },
  261. apiFilePrefix: "test-",
  262. moduleSuffix: ".test",
  263. sdkVersion: "test_current",
  264. annotation: "android.annotation.TestApi",
  265. unstable: true,
  266. })
  267. apiScopeModuleLib = initApiScope(&apiScope{
  268. name: "module-lib",
  269. extends: apiScopeSystem,
  270. // The module-lib scope is disabled by default in legacy mode.
  271. //
  272. // Enabling this would break existing usages.
  273. legacyEnabledStatus: func(module *SdkLibrary) bool {
  274. return false
  275. },
  276. scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
  277. return &module.sdkLibraryProperties.Module_lib
  278. },
  279. apiFilePrefix: "module-lib-",
  280. moduleSuffix: ".module_lib",
  281. sdkVersion: "module_current",
  282. annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES)",
  283. })
  284. apiScopeSystemServer = initApiScope(&apiScope{
  285. name: "system-server",
  286. extends: apiScopePublic,
  287. // The system-server scope can access the module-lib scope.
  288. //
  289. // A module that provides a system-server API is appended to the standard bootclasspath that is
  290. // used by the system server. So, it should be able to access module-lib APIs provided by
  291. // libraries on the bootclasspath.
  292. canAccess: apiScopeModuleLib,
  293. // The system-server scope is disabled by default in legacy mode.
  294. //
  295. // Enabling this would break existing usages.
  296. legacyEnabledStatus: func(module *SdkLibrary) bool {
  297. return false
  298. },
  299. scopeSpecificProperties: func(module *SdkLibrary) *ApiScopeProperties {
  300. return &module.sdkLibraryProperties.System_server
  301. },
  302. apiFilePrefix: "system-server-",
  303. moduleSuffix: ".system_server",
  304. sdkVersion: "system_server_current",
  305. annotation: "android.annotation.SystemApi(client=android.annotation.SystemApi.Client.SYSTEM_SERVER)",
  306. extraArgs: []string{
  307. "--hide-annotation", "android.annotation.Hide",
  308. // com.android.* classes are okay in this interface"
  309. "--hide", "InternalClasses",
  310. },
  311. })
  312. allApiScopes = apiScopes{
  313. apiScopePublic,
  314. apiScopeSystem,
  315. apiScopeTest,
  316. apiScopeModuleLib,
  317. apiScopeSystemServer,
  318. }
  319. )
  320. var (
  321. javaSdkLibrariesLock sync.Mutex
  322. )
  323. // TODO: these are big features that are currently missing
  324. // 1) disallowing linking to the runtime shared lib
  325. // 2) HTML generation
  326. func init() {
  327. RegisterSdkLibraryBuildComponents(android.InitRegistrationContext)
  328. android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
  329. javaSdkLibraries := javaSdkLibraries(ctx.Config())
  330. sort.Strings(*javaSdkLibraries)
  331. ctx.Strict("JAVA_SDK_LIBRARIES", strings.Join(*javaSdkLibraries, " "))
  332. })
  333. // Register sdk member types.
  334. android.RegisterSdkMemberType(javaSdkLibrarySdkMemberType)
  335. }
  336. func RegisterSdkLibraryBuildComponents(ctx android.RegistrationContext) {
  337. ctx.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
  338. ctx.RegisterModuleType("java_sdk_library_import", sdkLibraryImportFactory)
  339. }
  340. // Properties associated with each api scope.
  341. type ApiScopeProperties struct {
  342. // Indicates whether the api surface is generated.
  343. //
  344. // If this is set for any scope then all scopes must explicitly specify if they
  345. // are enabled. This is to prevent new usages from depending on legacy behavior.
  346. //
  347. // Otherwise, if this is not set for any scope then the default behavior is
  348. // scope specific so please refer to the scope specific property documentation.
  349. Enabled *bool
  350. // The sdk_version to use for building the stubs.
  351. //
  352. // If not specified then it will use an sdk_version determined as follows:
  353. //
  354. // 1) If the sdk_version specified on the java_sdk_library is none then this
  355. // will be none. This is used for java_sdk_library instances that are used
  356. // to create stubs that contribute to the core_current sdk version.
  357. // 2) Otherwise, it is assumed that this library extends but does not
  358. // contribute directly to a specific sdk_version and so this uses the
  359. // sdk_version appropriate for the api scope. e.g. public will use
  360. // sdk_version: current, system will use sdk_version: system_current, etc.
  361. //
  362. // This does not affect the sdk_version used for either generating the stubs source
  363. // or the API file. They both have to use the same sdk_version as is used for
  364. // compiling the implementation library.
  365. Sdk_version *string
  366. }
  367. type sdkLibraryProperties struct {
  368. // List of source files that are needed to compile the API, but are not part of runtime library.
  369. Api_srcs []string `android:"arch_variant"`
  370. // Visibility for impl library module. If not specified then defaults to the
  371. // visibility property.
  372. Impl_library_visibility []string
  373. // Visibility for stubs library modules. If not specified then defaults to the
  374. // visibility property.
  375. Stubs_library_visibility []string
  376. // Visibility for stubs source modules. If not specified then defaults to the
  377. // visibility property.
  378. Stubs_source_visibility []string
  379. // List of Java libraries that will be in the classpath when building the implementation lib
  380. Impl_only_libs []string `android:"arch_variant"`
  381. // List of Java libraries that will included in the implementation lib.
  382. Impl_only_static_libs []string `android:"arch_variant"`
  383. // List of Java libraries that will be in the classpath when building stubs
  384. Stub_only_libs []string `android:"arch_variant"`
  385. // List of Java libraries that will included in stub libraries
  386. Stub_only_static_libs []string `android:"arch_variant"`
  387. // list of package names that will be documented and publicized as API.
  388. // This allows the API to be restricted to a subset of the source files provided.
  389. // If this is unspecified then all the source files will be treated as being part
  390. // of the API.
  391. Api_packages []string
  392. // list of package names that must be hidden from the API
  393. Hidden_api_packages []string
  394. // the relative path to the directory containing the api specification files.
  395. // Defaults to "api".
  396. Api_dir *string
  397. // Determines whether a runtime implementation library is built; defaults to false.
  398. //
  399. // If true then it also prevents the module from being used as a shared module, i.e.
  400. // it is as if shared_library: false, was set.
  401. Api_only *bool
  402. // local files that are used within user customized droiddoc options.
  403. Droiddoc_option_files []string
  404. // additional droiddoc options.
  405. // Available variables for substitution:
  406. //
  407. // $(location <label>): the path to the droiddoc_option_files with name <label>
  408. Droiddoc_options []string
  409. // is set to true, Metalava will allow framework SDK to contain annotations.
  410. Annotations_enabled *bool
  411. // a list of top-level directories containing files to merge qualifier annotations
  412. // (i.e. those intended to be included in the stubs written) from.
  413. Merge_annotations_dirs []string
  414. // a list of top-level directories containing Java stub files to merge show/hide annotations from.
  415. Merge_inclusion_annotations_dirs []string
  416. // If set to true then don't create dist rules.
  417. No_dist *bool
  418. // The stem for the artifacts that are copied to the dist, if not specified
  419. // then defaults to the base module name.
  420. //
  421. // For each scope the following artifacts are copied to the apistubs/<scope>
  422. // directory in the dist.
  423. // * stubs impl jar -> <dist-stem>.jar
  424. // * API specification file -> api/<dist-stem>.txt
  425. // * Removed API specification file -> api/<dist-stem>-removed.txt
  426. //
  427. // Also used to construct the name of the filegroup (created by prebuilt_apis)
  428. // that references the latest released API and remove API specification files.
  429. // * API specification filegroup -> <dist-stem>.api.<scope>.latest
  430. // * Removed API specification filegroup -> <dist-stem>-removed.api.<scope>.latest
  431. // * API incompatibilities baseline filegroup -> <dist-stem>-incompatibilities.api.<scope>.latest
  432. Dist_stem *string
  433. // The subdirectory for the artifacts that are copied to the dist directory. If not specified
  434. // then defaults to "unknown". Should be set to "android" for anything that should be published
  435. // in the public Android SDK.
  436. Dist_group *string
  437. // A compatibility mode that allows historical API-tracking files to not exist.
  438. // Do not use.
  439. Unsafe_ignore_missing_latest_api bool
  440. // indicates whether system and test apis should be generated.
  441. Generate_system_and_test_apis bool `blueprint:"mutated"`
  442. // The properties specific to the public api scope
  443. //
  444. // Unless explicitly specified by using public.enabled the public api scope is
  445. // enabled by default in both legacy and non-legacy mode.
  446. Public ApiScopeProperties
  447. // The properties specific to the system api scope
  448. //
  449. // In legacy mode the system api scope is enabled by default when sdk_version
  450. // is set to something other than "none".
  451. //
  452. // In non-legacy mode the system api scope is disabled by default.
  453. System ApiScopeProperties
  454. // The properties specific to the test api scope
  455. //
  456. // In legacy mode the test api scope is enabled by default when sdk_version
  457. // is set to something other than "none".
  458. //
  459. // In non-legacy mode the test api scope is disabled by default.
  460. Test ApiScopeProperties
  461. // The properties specific to the module-lib api scope
  462. //
  463. // Unless explicitly specified by using test.enabled the module-lib api scope is
  464. // disabled by default.
  465. Module_lib ApiScopeProperties
  466. // The properties specific to the system-server api scope
  467. //
  468. // Unless explicitly specified by using test.enabled the module-lib api scope is
  469. // disabled by default.
  470. System_server ApiScopeProperties
  471. // Determines if the stubs are preferred over the implementation library
  472. // for linking, even when the client doesn't specify sdk_version. When this
  473. // is set to true, such clients are provided with the widest API surface that
  474. // this lib provides. Note however that this option doesn't affect the clients
  475. // that are in the same APEX as this library. In that case, the clients are
  476. // always linked with the implementation library. Default is false.
  477. Default_to_stubs *bool
  478. // Properties related to api linting.
  479. Api_lint struct {
  480. // Enable api linting.
  481. Enabled *bool
  482. }
  483. // TODO: determines whether to create HTML doc or not
  484. // Html_doc *bool
  485. }
  486. // Paths to outputs from java_sdk_library and java_sdk_library_import.
  487. //
  488. // Fields that are android.Paths are always set (during GenerateAndroidBuildActions).
  489. // OptionalPaths are always set by java_sdk_library but may not be set by
  490. // java_sdk_library_import as not all instances provide that information.
  491. type scopePaths struct {
  492. // The path (represented as Paths for convenience when returning) to the stubs header jar.
  493. //
  494. // That is the jar that is created by turbine.
  495. stubsHeaderPath android.Paths
  496. // The path (represented as Paths for convenience when returning) to the stubs implementation jar.
  497. //
  498. // This is not the implementation jar, it still only contains stubs.
  499. stubsImplPath android.Paths
  500. // The dex jar for the stubs.
  501. //
  502. // This is not the implementation jar, it still only contains stubs.
  503. stubsDexJarPath OptionalDexJarPath
  504. // The API specification file, e.g. system_current.txt.
  505. currentApiFilePath android.OptionalPath
  506. // The specification of API elements removed since the last release.
  507. removedApiFilePath android.OptionalPath
  508. // The stubs source jar.
  509. stubsSrcJar android.OptionalPath
  510. // Extracted annotations.
  511. annotationsZip android.OptionalPath
  512. // The path to the latest API file.
  513. latestApiPath android.OptionalPath
  514. // The path to the latest removed API file.
  515. latestRemovedApiPath android.OptionalPath
  516. }
  517. func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
  518. if ctx.OtherModuleHasProvider(dep, JavaInfoProvider) {
  519. lib := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
  520. paths.stubsHeaderPath = lib.HeaderJars
  521. paths.stubsImplPath = lib.ImplementationJars
  522. libDep := dep.(UsesLibraryDependency)
  523. paths.stubsDexJarPath = libDep.DexJarBuildPath()
  524. return nil
  525. } else {
  526. return fmt.Errorf("expected module that has JavaInfoProvider, e.g. java_library")
  527. }
  528. }
  529. func (paths *scopePaths) treatDepAsApiStubsProvider(dep android.Module, action func(provider ApiStubsProvider)) error {
  530. if apiStubsProvider, ok := dep.(ApiStubsProvider); ok {
  531. action(apiStubsProvider)
  532. return nil
  533. } else {
  534. return fmt.Errorf("expected module that implements ApiStubsProvider, e.g. droidstubs")
  535. }
  536. }
  537. func (paths *scopePaths) treatDepAsApiStubsSrcProvider(dep android.Module, action func(provider ApiStubsSrcProvider)) error {
  538. if apiStubsProvider, ok := dep.(ApiStubsSrcProvider); ok {
  539. action(apiStubsProvider)
  540. return nil
  541. } else {
  542. return fmt.Errorf("expected module that implements ApiStubsSrcProvider, e.g. droidstubs")
  543. }
  544. }
  545. func (paths *scopePaths) extractApiInfoFromApiStubsProvider(provider ApiStubsProvider) {
  546. paths.annotationsZip = android.OptionalPathForPath(provider.AnnotationsZip())
  547. paths.currentApiFilePath = android.OptionalPathForPath(provider.ApiFilePath())
  548. paths.removedApiFilePath = android.OptionalPathForPath(provider.RemovedApiFilePath())
  549. }
  550. func (paths *scopePaths) extractApiInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
  551. return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
  552. paths.extractApiInfoFromApiStubsProvider(provider)
  553. })
  554. }
  555. func (paths *scopePaths) extractStubsSourceInfoFromApiStubsProviders(provider ApiStubsSrcProvider) {
  556. paths.stubsSrcJar = android.OptionalPathForPath(provider.StubsSrcJar())
  557. }
  558. func (paths *scopePaths) extractStubsSourceInfoFromDep(ctx android.ModuleContext, dep android.Module) error {
  559. return paths.treatDepAsApiStubsSrcProvider(dep, func(provider ApiStubsSrcProvider) {
  560. paths.extractStubsSourceInfoFromApiStubsProviders(provider)
  561. })
  562. }
  563. func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx android.ModuleContext, dep android.Module) error {
  564. return paths.treatDepAsApiStubsProvider(dep, func(provider ApiStubsProvider) {
  565. paths.extractApiInfoFromApiStubsProvider(provider)
  566. paths.extractStubsSourceInfoFromApiStubsProviders(provider)
  567. })
  568. }
  569. func extractSingleOptionalOutputPath(dep android.Module) (android.OptionalPath, error) {
  570. var paths android.Paths
  571. if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok {
  572. paths = sourceFileProducer.Srcs()
  573. } else {
  574. return android.OptionalPath{}, fmt.Errorf("module %q does not produce source files", dep)
  575. }
  576. if len(paths) != 1 {
  577. return android.OptionalPath{}, fmt.Errorf("expected one path from %q, got %q", dep, paths)
  578. }
  579. return android.OptionalPathForPath(paths[0]), nil
  580. }
  581. func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
  582. outputPath, err := extractSingleOptionalOutputPath(dep)
  583. paths.latestApiPath = outputPath
  584. return err
  585. }
  586. func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
  587. outputPath, err := extractSingleOptionalOutputPath(dep)
  588. paths.latestRemovedApiPath = outputPath
  589. return err
  590. }
  591. type commonToSdkLibraryAndImportProperties struct {
  592. // The naming scheme to use for the components that this module creates.
  593. //
  594. // If not specified then it defaults to "default".
  595. //
  596. // This is a temporary mechanism to simplify conversion from separate modules for each
  597. // component that follow a different naming pattern to the default one.
  598. //
  599. // TODO(b/155480189) - Remove once naming inconsistencies have been resolved.
  600. Naming_scheme *string
  601. // Specifies whether this module can be used as an Android shared library; defaults
  602. // to true.
  603. //
  604. // An Android shared library is one that can be referenced in a <uses-library> element
  605. // in an AndroidManifest.xml.
  606. Shared_library *bool
  607. // Files containing information about supported java doc tags.
  608. Doctag_files []string `android:"path"`
  609. // Signals that this shared library is part of the bootclasspath starting
  610. // on the version indicated in this attribute.
  611. //
  612. // This will make platforms at this level and above to ignore
  613. // <uses-library> tags with this library name because the library is already
  614. // available
  615. On_bootclasspath_since *string
  616. // Signals that this shared library was part of the bootclasspath before
  617. // (but not including) the version indicated in this attribute.
  618. //
  619. // The system will automatically add a <uses-library> tag with this library to
  620. // apps that target any SDK less than the version indicated in this attribute.
  621. On_bootclasspath_before *string
  622. // Indicates that PackageManager should ignore this shared library if the
  623. // platform is below the version indicated in this attribute.
  624. //
  625. // This means that the device won't recognise this library as installed.
  626. Min_device_sdk *string
  627. // Indicates that PackageManager should ignore this shared library if the
  628. // platform is above the version indicated in this attribute.
  629. //
  630. // This means that the device won't recognise this library as installed.
  631. Max_device_sdk *string
  632. }
  633. // commonSdkLibraryAndImportModule defines the interface that must be provided by a module that
  634. // embeds the commonToSdkLibraryAndImport struct.
  635. type commonSdkLibraryAndImportModule interface {
  636. android.Module
  637. BaseModuleName() string
  638. }
  639. // Common code between sdk library and sdk library import
  640. type commonToSdkLibraryAndImport struct {
  641. module commonSdkLibraryAndImportModule
  642. scopePaths map[*apiScope]*scopePaths
  643. namingScheme sdkLibraryComponentNamingScheme
  644. commonSdkLibraryProperties commonToSdkLibraryAndImportProperties
  645. // Paths to commonSdkLibraryProperties.Doctag_files
  646. doctagPaths android.Paths
  647. // Functionality related to this being used as a component of a java_sdk_library.
  648. EmbeddableSdkLibraryComponent
  649. }
  650. func (c *commonToSdkLibraryAndImport) initCommon(module commonSdkLibraryAndImportModule) {
  651. c.module = module
  652. module.AddProperties(&c.commonSdkLibraryProperties)
  653. // Initialize this as an sdk library component.
  654. c.initSdkLibraryComponent(module)
  655. }
  656. func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
  657. schemeProperty := proptools.StringDefault(c.commonSdkLibraryProperties.Naming_scheme, "default")
  658. switch schemeProperty {
  659. case "default":
  660. c.namingScheme = &defaultNamingScheme{}
  661. default:
  662. ctx.PropertyErrorf("naming_scheme", "expected 'default' but was %q", schemeProperty)
  663. return false
  664. }
  665. namePtr := proptools.StringPtr(c.module.BaseModuleName())
  666. c.sdkLibraryComponentProperties.SdkLibraryName = namePtr
  667. // Only track this sdk library if this can be used as a shared library.
  668. if c.sharedLibrary() {
  669. // Use the name specified in the module definition as the owner.
  670. c.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack = namePtr
  671. }
  672. return true
  673. }
  674. // uniqueApexVariations provides common implementation of the ApexModule.UniqueApexVariations
  675. // method.
  676. func (c *commonToSdkLibraryAndImport) uniqueApexVariations() bool {
  677. // A java_sdk_library that is a shared library produces an XML file that makes the shared library
  678. // usable from an AndroidManifest.xml's <uses-library> entry. That XML file contains the name of
  679. // the APEX and so it needs a unique variation per APEX.
  680. return c.sharedLibrary()
  681. }
  682. func (c *commonToSdkLibraryAndImport) generateCommonBuildActions(ctx android.ModuleContext) {
  683. c.doctagPaths = android.PathsForModuleSrc(ctx, c.commonSdkLibraryProperties.Doctag_files)
  684. }
  685. // Module name of the runtime implementation library
  686. func (c *commonToSdkLibraryAndImport) implLibraryModuleName() string {
  687. return c.module.BaseModuleName() + ".impl"
  688. }
  689. // Module name of the XML file for the lib
  690. func (c *commonToSdkLibraryAndImport) xmlPermissionsModuleName() string {
  691. return c.module.BaseModuleName() + sdkXmlFileSuffix
  692. }
  693. // Name of the java_library module that compiles the stubs source.
  694. func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope) string {
  695. baseName := c.module.BaseModuleName()
  696. return c.namingScheme.stubsLibraryModuleName(apiScope, baseName)
  697. }
  698. // Name of the droidstubs module that generates the stubs source and may also
  699. // generate/check the API.
  700. func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
  701. baseName := c.module.BaseModuleName()
  702. return c.namingScheme.stubsSourceModuleName(apiScope, baseName)
  703. }
  704. // The component names for different outputs of the java_sdk_library.
  705. //
  706. // They are similar to the names used for the child modules it creates
  707. const (
  708. stubsSourceComponentName = "stubs.source"
  709. apiTxtComponentName = "api.txt"
  710. removedApiTxtComponentName = "removed-api.txt"
  711. annotationsComponentName = "annotations.zip"
  712. )
  713. // A regular expression to match tags that reference a specific stubs component.
  714. //
  715. // It will only match if given a valid scope and a valid component. It is verfy strict
  716. // to ensure it does not accidentally match a similar looking tag that should be processed
  717. // by the embedded Library.
  718. var tagSplitter = func() *regexp.Regexp {
  719. // Given a list of literal string items returns a regular expression that will
  720. // match any one of the items.
  721. choice := func(items ...string) string {
  722. return `\Q` + strings.Join(items, `\E|\Q`) + `\E`
  723. }
  724. // Regular expression to match one of the scopes.
  725. scopesRegexp := choice(allScopeNames...)
  726. // Regular expression to match one of the components.
  727. componentsRegexp := choice(stubsSourceComponentName, apiTxtComponentName, removedApiTxtComponentName, annotationsComponentName)
  728. // Regular expression to match any combination of one scope and one component.
  729. return regexp.MustCompile(fmt.Sprintf(`^\.(%s)\.(%s)$`, scopesRegexp, componentsRegexp))
  730. }()
  731. // For OutputFileProducer interface
  732. //
  733. // .<scope>.<component name>, for all ComponentNames (for example: .public.removed-api.txt)
  734. func (c *commonToSdkLibraryAndImport) commonOutputFiles(tag string) (android.Paths, error) {
  735. if groups := tagSplitter.FindStringSubmatch(tag); groups != nil {
  736. scopeName := groups[1]
  737. component := groups[2]
  738. if scope, ok := scopeByName[scopeName]; ok {
  739. paths := c.findScopePaths(scope)
  740. if paths == nil {
  741. return nil, fmt.Errorf("%q does not provide api scope %s", c.module.BaseModuleName(), scopeName)
  742. }
  743. switch component {
  744. case stubsSourceComponentName:
  745. if paths.stubsSrcJar.Valid() {
  746. return android.Paths{paths.stubsSrcJar.Path()}, nil
  747. }
  748. case apiTxtComponentName:
  749. if paths.currentApiFilePath.Valid() {
  750. return android.Paths{paths.currentApiFilePath.Path()}, nil
  751. }
  752. case removedApiTxtComponentName:
  753. if paths.removedApiFilePath.Valid() {
  754. return android.Paths{paths.removedApiFilePath.Path()}, nil
  755. }
  756. case annotationsComponentName:
  757. if paths.annotationsZip.Valid() {
  758. return android.Paths{paths.annotationsZip.Path()}, nil
  759. }
  760. }
  761. return nil, fmt.Errorf("%s not available for api scope %s", component, scopeName)
  762. } else {
  763. return nil, fmt.Errorf("unknown scope %s in %s", scope, tag)
  764. }
  765. } else {
  766. switch tag {
  767. case ".doctags":
  768. if c.doctagPaths != nil {
  769. return c.doctagPaths, nil
  770. } else {
  771. return nil, fmt.Errorf("no doctag_files specified on %s", c.module.BaseModuleName())
  772. }
  773. }
  774. return nil, nil
  775. }
  776. }
  777. func (c *commonToSdkLibraryAndImport) getScopePathsCreateIfNeeded(scope *apiScope) *scopePaths {
  778. if c.scopePaths == nil {
  779. c.scopePaths = make(map[*apiScope]*scopePaths)
  780. }
  781. paths := c.scopePaths[scope]
  782. if paths == nil {
  783. paths = &scopePaths{}
  784. c.scopePaths[scope] = paths
  785. }
  786. return paths
  787. }
  788. func (c *commonToSdkLibraryAndImport) findScopePaths(scope *apiScope) *scopePaths {
  789. if c.scopePaths == nil {
  790. return nil
  791. }
  792. return c.scopePaths[scope]
  793. }
  794. // If this does not support the requested api scope then find the closest available
  795. // scope it does support. Returns nil if no such scope is available.
  796. func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths {
  797. for s := scope; s != nil; s = s.canAccess {
  798. if paths := c.findScopePaths(s); paths != nil {
  799. return paths
  800. }
  801. }
  802. // This should never happen outside tests as public should be the base scope for every
  803. // scope and is enabled by default.
  804. return nil
  805. }
  806. func (c *commonToSdkLibraryAndImport) selectHeaderJarsForSdkVersion(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
  807. // If a specific numeric version has been requested then use prebuilt versions of the sdk.
  808. if !sdkVersion.ApiLevel.IsPreview() {
  809. return PrebuiltJars(ctx, c.module.BaseModuleName(), sdkVersion)
  810. }
  811. paths := c.selectScopePaths(ctx, sdkVersion.Kind)
  812. if paths == nil {
  813. return nil
  814. }
  815. return paths.stubsHeaderPath
  816. }
  817. // selectScopePaths returns the *scopePaths appropriate for the specific kind.
  818. //
  819. // If the module does not support the specific kind then it will return the *scopePaths for the
  820. // closest kind which is a subset of the requested kind. e.g. if requesting android.SdkModule then
  821. // it will return *scopePaths for android.SdkSystem if available or android.SdkPublic of not.
  822. func (c *commonToSdkLibraryAndImport) selectScopePaths(ctx android.BaseModuleContext, kind android.SdkKind) *scopePaths {
  823. apiScope := sdkKindToApiScope(kind)
  824. paths := c.findClosestScopePath(apiScope)
  825. if paths == nil {
  826. var scopes []string
  827. for _, s := range allApiScopes {
  828. if c.findScopePaths(s) != nil {
  829. scopes = append(scopes, s.name)
  830. }
  831. }
  832. ctx.ModuleErrorf("requires api scope %s from %s but it only has %q available", apiScope.name, c.module.BaseModuleName(), scopes)
  833. return nil
  834. }
  835. return paths
  836. }
  837. // sdkKindToApiScope maps from android.SdkKind to apiScope.
  838. func sdkKindToApiScope(kind android.SdkKind) *apiScope {
  839. var apiScope *apiScope
  840. switch kind {
  841. case android.SdkSystem:
  842. apiScope = apiScopeSystem
  843. case android.SdkModule:
  844. apiScope = apiScopeModuleLib
  845. case android.SdkTest:
  846. apiScope = apiScopeTest
  847. case android.SdkSystemServer:
  848. apiScope = apiScopeSystemServer
  849. default:
  850. apiScope = apiScopePublic
  851. }
  852. return apiScope
  853. }
  854. // to satisfy SdkLibraryDependency interface
  855. func (c *commonToSdkLibraryAndImport) SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath {
  856. paths := c.selectScopePaths(ctx, kind)
  857. if paths == nil {
  858. return makeUnsetDexJarPath()
  859. }
  860. return paths.stubsDexJarPath
  861. }
  862. // to satisfy SdkLibraryDependency interface
  863. func (c *commonToSdkLibraryAndImport) SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath {
  864. apiScope := sdkKindToApiScope(kind)
  865. paths := c.findScopePaths(apiScope)
  866. if paths == nil {
  867. return android.OptionalPath{}
  868. }
  869. return paths.removedApiFilePath
  870. }
  871. func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} {
  872. componentProps := &struct {
  873. SdkLibraryName *string
  874. SdkLibraryToImplicitlyTrack *string
  875. }{}
  876. namePtr := proptools.StringPtr(c.module.BaseModuleName())
  877. componentProps.SdkLibraryName = namePtr
  878. if c.sharedLibrary() {
  879. // Mark the stubs library as being components of this java_sdk_library so that
  880. // any app that includes code which depends (directly or indirectly) on the stubs
  881. // library will have the appropriate <uses-library> invocation inserted into its
  882. // manifest if necessary.
  883. componentProps.SdkLibraryToImplicitlyTrack = namePtr
  884. }
  885. return componentProps
  886. }
  887. func (c *commonToSdkLibraryAndImport) sharedLibrary() bool {
  888. return proptools.BoolDefault(c.commonSdkLibraryProperties.Shared_library, true)
  889. }
  890. // Check if the stub libraries should be compiled for dex
  891. func (c *commonToSdkLibraryAndImport) stubLibrariesCompiledForDex() bool {
  892. // Always compile the dex file files for the stub libraries if they will be used on the
  893. // bootclasspath.
  894. return !c.sharedLibrary()
  895. }
  896. // Properties related to the use of a module as an component of a java_sdk_library.
  897. type SdkLibraryComponentProperties struct {
  898. // The name of the java_sdk_library/_import module.
  899. SdkLibraryName *string `blueprint:"mutated"`
  900. // The name of the java_sdk_library/_import to add to a <uses-library> entry
  901. // in the AndroidManifest.xml of any Android app that includes code that references
  902. // this module. If not set then no java_sdk_library/_import is tracked.
  903. SdkLibraryToImplicitlyTrack *string `blueprint:"mutated"`
  904. }
  905. // Structure to be embedded in a module struct that needs to support the
  906. // SdkLibraryComponentDependency interface.
  907. type EmbeddableSdkLibraryComponent struct {
  908. sdkLibraryComponentProperties SdkLibraryComponentProperties
  909. }
  910. func (e *EmbeddableSdkLibraryComponent) initSdkLibraryComponent(module android.Module) {
  911. module.AddProperties(&e.sdkLibraryComponentProperties)
  912. }
  913. // to satisfy SdkLibraryComponentDependency
  914. func (e *EmbeddableSdkLibraryComponent) SdkLibraryName() *string {
  915. return e.sdkLibraryComponentProperties.SdkLibraryName
  916. }
  917. // to satisfy SdkLibraryComponentDependency
  918. func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string {
  919. // For shared libraries, this is the same as the SDK library name. If a Java library or app
  920. // depends on a component library (e.g. a stub library) it still needs to know the name of the
  921. // run-time library and the corresponding module that provides the implementation. This name is
  922. // passed to manifest_fixer (to be added to AndroidManifest.xml) and added to CLC (to be used
  923. // in dexpreopt).
  924. //
  925. // For non-shared SDK (component or not) libraries this returns `nil`, as they are not
  926. // <uses-library> and should not be added to the manifest or to CLC.
  927. return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack
  928. }
  929. // Implemented by modules that are (or possibly could be) a component of a java_sdk_library
  930. // (including the java_sdk_library) itself.
  931. type SdkLibraryComponentDependency interface {
  932. UsesLibraryDependency
  933. // SdkLibraryName returns the name of the java_sdk_library/_import module.
  934. SdkLibraryName() *string
  935. // The name of the implementation library for the optional SDK library or nil, if there isn't one.
  936. OptionalSdkLibraryImplementation() *string
  937. }
  938. // Make sure that all the module types that are components of java_sdk_library/_import
  939. // and which can be referenced (directly or indirectly) from an android app implement
  940. // the SdkLibraryComponentDependency interface.
  941. var _ SdkLibraryComponentDependency = (*Library)(nil)
  942. var _ SdkLibraryComponentDependency = (*Import)(nil)
  943. var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil)
  944. var _ SdkLibraryComponentDependency = (*SdkLibraryImport)(nil)
  945. // Provides access to sdk_version related files, e.g. header and implementation jars.
  946. type SdkLibraryDependency interface {
  947. SdkLibraryComponentDependency
  948. // Get the header jars appropriate for the supplied sdk_version.
  949. //
  950. // These are turbine generated jars so they only change if the externals of the
  951. // class changes but it does not contain and implementation or JavaDoc.
  952. SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
  953. // Get the implementation jars appropriate for the supplied sdk version.
  954. //
  955. // These are either the implementation jar for the whole sdk library or the implementation
  956. // jars for the stubs. The latter should only be needed when generating JavaDoc as otherwise
  957. // they are identical to the corresponding header jars.
  958. SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths
  959. // SdkApiStubDexJar returns the dex jar for the stubs. It is needed by the hiddenapi processing
  960. // tool which processes dex files.
  961. SdkApiStubDexJar(ctx android.BaseModuleContext, kind android.SdkKind) OptionalDexJarPath
  962. // SdkRemovedTxtFile returns the optional path to the removed.txt file for the specified sdk kind.
  963. SdkRemovedTxtFile(ctx android.BaseModuleContext, kind android.SdkKind) android.OptionalPath
  964. // sharedLibrary returns true if this can be used as a shared library.
  965. sharedLibrary() bool
  966. }
  967. type SdkLibrary struct {
  968. Library
  969. sdkLibraryProperties sdkLibraryProperties
  970. // Map from api scope to the scope specific property structure.
  971. scopeToProperties map[*apiScope]*ApiScopeProperties
  972. commonToSdkLibraryAndImport
  973. }
  974. var _ SdkLibraryDependency = (*SdkLibrary)(nil)
  975. func (module *SdkLibrary) generateTestAndSystemScopesByDefault() bool {
  976. return module.sdkLibraryProperties.Generate_system_and_test_apis
  977. }
  978. func (module *SdkLibrary) getGeneratedApiScopes(ctx android.EarlyModuleContext) apiScopes {
  979. // Check to see if any scopes have been explicitly enabled. If any have then all
  980. // must be.
  981. anyScopesExplicitlyEnabled := false
  982. for _, scope := range allApiScopes {
  983. scopeProperties := module.scopeToProperties[scope]
  984. if scopeProperties.Enabled != nil {
  985. anyScopesExplicitlyEnabled = true
  986. break
  987. }
  988. }
  989. var generatedScopes apiScopes
  990. enabledScopes := make(map[*apiScope]struct{})
  991. for _, scope := range allApiScopes {
  992. scopeProperties := module.scopeToProperties[scope]
  993. // If any scopes are explicitly enabled then ignore the legacy enabled status.
  994. // This is to ensure that any new usages of this module type do not rely on legacy
  995. // behaviour.
  996. defaultEnabledStatus := false
  997. if anyScopesExplicitlyEnabled {
  998. defaultEnabledStatus = scope.defaultEnabledStatus
  999. } else {
  1000. defaultEnabledStatus = scope.legacyEnabledStatus(module)
  1001. }
  1002. enabled := proptools.BoolDefault(scopeProperties.Enabled, defaultEnabledStatus)
  1003. if enabled {
  1004. enabledScopes[scope] = struct{}{}
  1005. generatedScopes = append(generatedScopes, scope)
  1006. }
  1007. }
  1008. // Now check to make sure that any scope that is extended by an enabled scope is also
  1009. // enabled.
  1010. for _, scope := range allApiScopes {
  1011. if _, ok := enabledScopes[scope]; ok {
  1012. extends := scope.extends
  1013. if extends != nil {
  1014. if _, ok := enabledScopes[extends]; !ok {
  1015. ctx.ModuleErrorf("enabled api scope %q depends on disabled scope %q", scope, extends)
  1016. }
  1017. }
  1018. }
  1019. }
  1020. return generatedScopes
  1021. }
  1022. var _ android.ModuleWithMinSdkVersionCheck = (*SdkLibrary)(nil)
  1023. func (module *SdkLibrary) CheckMinSdkVersion(ctx android.ModuleContext) {
  1024. android.CheckMinSdkVersion(ctx, module.MinSdkVersion(ctx).ApiLevel, func(c android.ModuleContext, do android.PayloadDepsCallback) {
  1025. ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
  1026. isExternal := !module.depIsInSameApex(ctx, child)
  1027. if am, ok := child.(android.ApexModule); ok {
  1028. if !do(ctx, parent, am, isExternal) {
  1029. return false
  1030. }
  1031. }
  1032. return !isExternal
  1033. })
  1034. })
  1035. }
  1036. type sdkLibraryComponentTag struct {
  1037. blueprint.BaseDependencyTag
  1038. name string
  1039. }
  1040. // Mark this tag so dependencies that use it are excluded from visibility enforcement.
  1041. func (t sdkLibraryComponentTag) ExcludeFromVisibilityEnforcement() {}
  1042. var xmlPermissionsFileTag = sdkLibraryComponentTag{name: "xml-permissions-file"}
  1043. func IsXmlPermissionsFileDepTag(depTag blueprint.DependencyTag) bool {
  1044. if dt, ok := depTag.(sdkLibraryComponentTag); ok {
  1045. return dt == xmlPermissionsFileTag
  1046. }
  1047. return false
  1048. }
  1049. var implLibraryTag = sdkLibraryComponentTag{name: "impl-library"}
  1050. // Add the dependencies on the child modules in the component deps mutator.
  1051. func (module *SdkLibrary) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
  1052. for _, apiScope := range module.getGeneratedApiScopes(ctx) {
  1053. // Add dependencies to the stubs library
  1054. ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsLibraryModuleName(apiScope))
  1055. // Add a dependency on the stubs source in order to access both stubs source and api information.
  1056. ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceModuleName(apiScope))
  1057. if module.compareAgainstLatestApi(apiScope) {
  1058. // Add dependencies on the latest finalized version of the API .txt file.
  1059. latestApiModuleName := module.latestApiModuleName(apiScope)
  1060. ctx.AddDependency(module, apiScope.latestApiModuleTag, latestApiModuleName)
  1061. // Add dependencies on the latest finalized version of the remove API .txt file.
  1062. latestRemovedApiModuleName := module.latestRemovedApiModuleName(apiScope)
  1063. ctx.AddDependency(module, apiScope.latestRemovedApiModuleTag, latestRemovedApiModuleName)
  1064. }
  1065. }
  1066. if module.requiresRuntimeImplementationLibrary() {
  1067. // Add dependency to the rule for generating the implementation library.
  1068. ctx.AddDependency(module, implLibraryTag, module.implLibraryModuleName())
  1069. if module.sharedLibrary() {
  1070. // Add dependency to the rule for generating the xml permissions file
  1071. ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlPermissionsModuleName())
  1072. }
  1073. }
  1074. }
  1075. // Add other dependencies as normal.
  1076. func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
  1077. var missingApiModules []string
  1078. for _, apiScope := range module.getGeneratedApiScopes(ctx) {
  1079. if apiScope.unstable {
  1080. continue
  1081. }
  1082. if m := module.latestApiModuleName(apiScope); !ctx.OtherModuleExists(m) {
  1083. missingApiModules = append(missingApiModules, m)
  1084. }
  1085. if m := module.latestRemovedApiModuleName(apiScope); !ctx.OtherModuleExists(m) {
  1086. missingApiModules = append(missingApiModules, m)
  1087. }
  1088. if m := module.latestIncompatibilitiesModuleName(apiScope); !ctx.OtherModuleExists(m) {
  1089. missingApiModules = append(missingApiModules, m)
  1090. }
  1091. }
  1092. if len(missingApiModules) != 0 && !module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api {
  1093. m := module.Name() + " is missing tracking files for previously released library versions.\n"
  1094. m += "You need to do one of the following:\n"
  1095. m += "- Add `unsafe_ignore_missing_latest_api: true` to your blueprint (to disable compat tracking)\n"
  1096. m += "- Add a set of prebuilt txt files representing the last released version of this library for compat checking.\n"
  1097. m += " (the current set of API files can be used as a seed for this compatibility tracking\n"
  1098. m += "\n"
  1099. m += "The following filegroup modules are missing:\n "
  1100. m += strings.Join(missingApiModules, "\n ") + "\n"
  1101. m += "Please see the documentation of the prebuilt_apis module type (and a usage example in prebuilts/sdk) for a convenient way to generate these."
  1102. ctx.ModuleErrorf(m)
  1103. }
  1104. if module.requiresRuntimeImplementationLibrary() {
  1105. // Only add the deps for the library if it is actually going to be built.
  1106. module.Library.deps(ctx)
  1107. }
  1108. }
  1109. func (module *SdkLibrary) OutputFiles(tag string) (android.Paths, error) {
  1110. paths, err := module.commonOutputFiles(tag)
  1111. if paths != nil || err != nil {
  1112. return paths, err
  1113. }
  1114. if module.requiresRuntimeImplementationLibrary() {
  1115. return module.Library.OutputFiles(tag)
  1116. }
  1117. if tag == "" {
  1118. return nil, nil
  1119. }
  1120. return nil, fmt.Errorf("unsupported module reference tag %q", tag)
  1121. }
  1122. func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  1123. if proptools.String(module.deviceProperties.Min_sdk_version) != "" {
  1124. module.CheckMinSdkVersion(ctx)
  1125. }
  1126. module.generateCommonBuildActions(ctx)
  1127. // Only build an implementation library if required.
  1128. if module.requiresRuntimeImplementationLibrary() {
  1129. module.Library.GenerateAndroidBuildActions(ctx)
  1130. }
  1131. // Collate the components exported by this module. All scope specific modules are exported but
  1132. // the impl and xml component modules are not.
  1133. exportedComponents := map[string]struct{}{}
  1134. // Record the paths to the header jars of the library (stubs and impl).
  1135. // When this java_sdk_library is depended upon from others via "libs" property,
  1136. // the recorded paths will be returned depending on the link type of the caller.
  1137. ctx.VisitDirectDeps(func(to android.Module) {
  1138. tag := ctx.OtherModuleDependencyTag(to)
  1139. // Extract information from any of the scope specific dependencies.
  1140. if scopeTag, ok := tag.(scopeDependencyTag); ok {
  1141. apiScope := scopeTag.apiScope
  1142. scopePaths := module.getScopePathsCreateIfNeeded(apiScope)
  1143. // Extract information from the dependency. The exact information extracted
  1144. // is determined by the nature of the dependency which is determined by the tag.
  1145. scopeTag.extractDepInfo(ctx, to, scopePaths)
  1146. exportedComponents[ctx.OtherModuleName(to)] = struct{}{}
  1147. }
  1148. })
  1149. // Make the set of components exported by this module available for use elsewhere.
  1150. exportedComponentInfo := android.ExportedComponentsInfo{Components: android.SortedStringKeys(exportedComponents)}
  1151. ctx.SetProvider(android.ExportedComponentsInfoProvider, exportedComponentInfo)
  1152. // Provide additional information for inclusion in an sdk's generated .info file.
  1153. additionalSdkInfo := map[string]interface{}{}
  1154. additionalSdkInfo["dist_stem"] = module.distStem()
  1155. baseModuleName := module.distStem()
  1156. scopes := map[string]interface{}{}
  1157. additionalSdkInfo["scopes"] = scopes
  1158. for scope, scopePaths := range module.scopePaths {
  1159. scopeInfo := map[string]interface{}{}
  1160. scopes[scope.name] = scopeInfo
  1161. scopeInfo["current_api"] = scope.snapshotRelativeCurrentApiTxtPath(baseModuleName)
  1162. scopeInfo["removed_api"] = scope.snapshotRelativeRemovedApiTxtPath(baseModuleName)
  1163. if p := scopePaths.latestApiPath; p.Valid() {
  1164. scopeInfo["latest_api"] = p.Path().String()
  1165. }
  1166. if p := scopePaths.latestRemovedApiPath; p.Valid() {
  1167. scopeInfo["latest_removed_api"] = p.Path().String()
  1168. }
  1169. }
  1170. ctx.SetProvider(android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo})
  1171. }
  1172. func (module *SdkLibrary) AndroidMkEntries() []android.AndroidMkEntries {
  1173. if !module.requiresRuntimeImplementationLibrary() {
  1174. return nil
  1175. }
  1176. entriesList := module.Library.AndroidMkEntries()
  1177. if module.sharedLibrary() {
  1178. entries := &entriesList[0]
  1179. entries.Required = append(entries.Required, module.xmlPermissionsModuleName())
  1180. }
  1181. return entriesList
  1182. }
  1183. // The dist path of the stub artifacts
  1184. func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
  1185. return path.Join("apistubs", module.distGroup(), apiScope.name)
  1186. }
  1187. // Get the sdk version for use when compiling the stubs library.
  1188. func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.EarlyModuleContext, apiScope *apiScope) string {
  1189. scopeProperties := module.scopeToProperties[apiScope]
  1190. if scopeProperties.Sdk_version != nil {
  1191. return proptools.String(scopeProperties.Sdk_version)
  1192. }
  1193. sdkDep := decodeSdkDep(mctx, android.SdkContext(&module.Library))
  1194. if sdkDep.hasStandardLibs() {
  1195. // If building against a standard sdk then use the sdk version appropriate for the scope.
  1196. return apiScope.sdkVersion
  1197. } else {
  1198. // Otherwise, use no system module.
  1199. return "none"
  1200. }
  1201. }
  1202. func (module *SdkLibrary) distStem() string {
  1203. return proptools.StringDefault(module.sdkLibraryProperties.Dist_stem, module.BaseModuleName())
  1204. }
  1205. // distGroup returns the subdirectory of the dist path of the stub artifacts.
  1206. func (module *SdkLibrary) distGroup() string {
  1207. return proptools.StringDefault(module.sdkLibraryProperties.Dist_group, "unknown")
  1208. }
  1209. func latestPrebuiltApiModuleName(name string, apiScope *apiScope) string {
  1210. return PrebuiltApiModuleName(name, apiScope.name, "latest")
  1211. }
  1212. func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
  1213. return ":" + module.latestApiModuleName(apiScope)
  1214. }
  1215. func (module *SdkLibrary) latestApiModuleName(apiScope *apiScope) string {
  1216. return latestPrebuiltApiModuleName(module.distStem(), apiScope)
  1217. }
  1218. func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope *apiScope) string {
  1219. return ":" + module.latestRemovedApiModuleName(apiScope)
  1220. }
  1221. func (module *SdkLibrary) latestRemovedApiModuleName(apiScope *apiScope) string {
  1222. return latestPrebuiltApiModuleName(module.distStem()+"-removed", apiScope)
  1223. }
  1224. func (module *SdkLibrary) latestIncompatibilitiesFilegroupName(apiScope *apiScope) string {
  1225. return ":" + module.latestIncompatibilitiesModuleName(apiScope)
  1226. }
  1227. func (module *SdkLibrary) latestIncompatibilitiesModuleName(apiScope *apiScope) string {
  1228. return latestPrebuiltApiModuleName(module.distStem()+"-incompatibilities", apiScope)
  1229. }
  1230. func childModuleVisibility(childVisibility []string) []string {
  1231. if childVisibility == nil {
  1232. // No child visibility set. The child will use the visibility of the sdk_library.
  1233. return nil
  1234. }
  1235. // Prepend an override to ignore the sdk_library's visibility, and rely on the child visibility.
  1236. var visibility []string
  1237. visibility = append(visibility, "//visibility:override")
  1238. visibility = append(visibility, childVisibility...)
  1239. return visibility
  1240. }
  1241. // Creates the implementation java library
  1242. func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext) {
  1243. visibility := childModuleVisibility(module.sdkLibraryProperties.Impl_library_visibility)
  1244. props := struct {
  1245. Name *string
  1246. Visibility []string
  1247. Instrument bool
  1248. Libs []string
  1249. Static_libs []string
  1250. Apex_available []string
  1251. }{
  1252. Name: proptools.StringPtr(module.implLibraryModuleName()),
  1253. Visibility: visibility,
  1254. // Set the instrument property to ensure it is instrumented when instrumentation is required.
  1255. Instrument: true,
  1256. // Set the impl_only libs. Note that the module's "Libs" get appended as well, via the
  1257. // addition of &module.properties below.
  1258. Libs: module.sdkLibraryProperties.Impl_only_libs,
  1259. // Set the impl_only static libs. Note that the module's "static_libs" get appended as well, via the
  1260. // addition of &module.properties below.
  1261. Static_libs: module.sdkLibraryProperties.Impl_only_static_libs,
  1262. // Pass the apex_available settings down so that the impl library can be statically
  1263. // embedded within a library that is added to an APEX. Needed for updatable-media.
  1264. Apex_available: module.ApexAvailable(),
  1265. }
  1266. properties := []interface{}{
  1267. &module.properties,
  1268. &module.protoProperties,
  1269. &module.deviceProperties,
  1270. &module.dexProperties,
  1271. &module.dexpreoptProperties,
  1272. &module.linter.properties,
  1273. &props,
  1274. module.sdkComponentPropertiesForChildLibrary(),
  1275. }
  1276. mctx.CreateModule(LibraryFactory, properties...)
  1277. }
  1278. // Creates a static java library that has API stubs
  1279. func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
  1280. props := struct {
  1281. Name *string
  1282. Visibility []string
  1283. Srcs []string
  1284. Installable *bool
  1285. Sdk_version *string
  1286. System_modules *string
  1287. Patch_module *string
  1288. Libs []string
  1289. Static_libs []string
  1290. Compile_dex *bool
  1291. Java_version *string
  1292. Openjdk9 struct {
  1293. Srcs []string
  1294. Javacflags []string
  1295. }
  1296. Dist struct {
  1297. Targets []string
  1298. Dest *string
  1299. Dir *string
  1300. Tag *string
  1301. }
  1302. }{}
  1303. props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
  1304. props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
  1305. // sources are generated from the droiddoc
  1306. props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
  1307. sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
  1308. props.Sdk_version = proptools.StringPtr(sdkVersion)
  1309. props.System_modules = module.deviceProperties.System_modules
  1310. props.Patch_module = module.properties.Patch_module
  1311. props.Installable = proptools.BoolPtr(false)
  1312. props.Libs = module.sdkLibraryProperties.Stub_only_libs
  1313. props.Static_libs = module.sdkLibraryProperties.Stub_only_static_libs
  1314. // The stub-annotations library contains special versions of the annotations
  1315. // with CLASS retention policy, so that they're kept.
  1316. if proptools.Bool(module.sdkLibraryProperties.Annotations_enabled) {
  1317. props.Libs = append(props.Libs, "stub-annotations")
  1318. }
  1319. props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
  1320. props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
  1321. // We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
  1322. // interop with older developer tools that don't support 1.9.
  1323. props.Java_version = proptools.StringPtr("1.8")
  1324. // The imports need to be compiled to dex if the java_sdk_library requests it.
  1325. compileDex := module.dexProperties.Compile_dex
  1326. if module.stubLibrariesCompiledForDex() {
  1327. compileDex = proptools.BoolPtr(true)
  1328. }
  1329. props.Compile_dex = compileDex
  1330. // Dist the class jar artifact for sdk builds.
  1331. if !Bool(module.sdkLibraryProperties.No_dist) {
  1332. props.Dist.Targets = []string{"sdk", "win_sdk"}
  1333. props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
  1334. props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
  1335. props.Dist.Tag = proptools.StringPtr(".jar")
  1336. }
  1337. mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
  1338. }
  1339. // Creates a droidstubs module that creates stubs source files from the given full source
  1340. // files and also updates and checks the API specification files.
  1341. func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope, name string, scopeSpecificDroidstubsArgs []string) {
  1342. props := struct {
  1343. Name *string
  1344. Visibility []string
  1345. Srcs []string
  1346. Installable *bool
  1347. Sdk_version *string
  1348. System_modules *string
  1349. Libs []string
  1350. Output_javadoc_comments *bool
  1351. Arg_files []string
  1352. Args *string
  1353. Java_version *string
  1354. Annotations_enabled *bool
  1355. Merge_annotations_dirs []string
  1356. Merge_inclusion_annotations_dirs []string
  1357. Generate_stubs *bool
  1358. Previous_api *string
  1359. Check_api struct {
  1360. Current ApiToCheck
  1361. Last_released ApiToCheck
  1362. Api_lint struct {
  1363. Enabled *bool
  1364. New_since *string
  1365. Baseline_file *string
  1366. }
  1367. }
  1368. Aidl struct {
  1369. Include_dirs []string
  1370. Local_include_dirs []string
  1371. }
  1372. Dists []android.Dist
  1373. }{}
  1374. // The stubs source processing uses the same compile time classpath when extracting the
  1375. // API from the implementation library as it does when compiling it. i.e. the same
  1376. // * sdk version
  1377. // * system_modules
  1378. // * libs (static_libs/libs)
  1379. props.Name = proptools.StringPtr(name)
  1380. props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_source_visibility)
  1381. props.Srcs = append(props.Srcs, module.properties.Srcs...)
  1382. props.Srcs = append(props.Srcs, module.sdkLibraryProperties.Api_srcs...)
  1383. props.Sdk_version = module.deviceProperties.Sdk_version
  1384. props.System_modules = module.deviceProperties.System_modules
  1385. props.Installable = proptools.BoolPtr(false)
  1386. // A droiddoc module has only one Libs property and doesn't distinguish between
  1387. // shared libs and static libs. So we need to add both of these libs to Libs property.
  1388. props.Libs = module.properties.Libs
  1389. props.Libs = append(props.Libs, module.properties.Static_libs...)
  1390. props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...)
  1391. props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
  1392. props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
  1393. props.Java_version = module.properties.Java_version
  1394. props.Annotations_enabled = module.sdkLibraryProperties.Annotations_enabled
  1395. props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
  1396. props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
  1397. droidstubsArgs := []string{}
  1398. if len(module.sdkLibraryProperties.Api_packages) != 0 {
  1399. droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
  1400. }
  1401. if len(module.sdkLibraryProperties.Hidden_api_packages) != 0 {
  1402. droidstubsArgs = append(droidstubsArgs,
  1403. android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package "))
  1404. }
  1405. droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
  1406. disabledWarnings := []string{
  1407. "BroadcastBehavior",
  1408. "DeprecationMismatch",
  1409. "HiddenSuperclass",
  1410. "HiddenTypeParameter",
  1411. "MissingPermission",
  1412. "SdkConstant",
  1413. "Todo",
  1414. "Typo",
  1415. "UnavailableSymbol",
  1416. }
  1417. droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
  1418. // Output Javadoc comments for public scope.
  1419. if apiScope == apiScopePublic {
  1420. props.Output_javadoc_comments = proptools.BoolPtr(true)
  1421. }
  1422. // Add in scope specific arguments.
  1423. droidstubsArgs = append(droidstubsArgs, scopeSpecificDroidstubsArgs...)
  1424. props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
  1425. props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
  1426. // List of APIs identified from the provided source files are created. They are later
  1427. // compared against to the not-yet-released (a.k.a current) list of APIs and to the
  1428. // last-released (a.k.a numbered) list of API.
  1429. currentApiFileName := apiScope.apiFilePrefix + "current.txt"
  1430. removedApiFileName := apiScope.apiFilePrefix + "removed.txt"
  1431. apiDir := module.getApiDir()
  1432. currentApiFileName = path.Join(apiDir, currentApiFileName)
  1433. removedApiFileName = path.Join(apiDir, removedApiFileName)
  1434. // check against the not-yet-release API
  1435. props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
  1436. props.Check_api.Current.Removed_api_file = proptools.StringPtr(removedApiFileName)
  1437. if module.compareAgainstLatestApi(apiScope) {
  1438. // check against the latest released API
  1439. latestApiFilegroupName := proptools.StringPtr(module.latestApiFilegroupName(apiScope))
  1440. props.Previous_api = latestApiFilegroupName
  1441. props.Check_api.Last_released.Api_file = latestApiFilegroupName
  1442. props.Check_api.Last_released.Removed_api_file = proptools.StringPtr(
  1443. module.latestRemovedApiFilegroupName(apiScope))
  1444. props.Check_api.Last_released.Baseline_file = proptools.StringPtr(
  1445. module.latestIncompatibilitiesFilegroupName(apiScope))
  1446. if proptools.Bool(module.sdkLibraryProperties.Api_lint.Enabled) {
  1447. // Enable api lint.
  1448. props.Check_api.Api_lint.Enabled = proptools.BoolPtr(true)
  1449. props.Check_api.Api_lint.New_since = latestApiFilegroupName
  1450. // If it exists then pass a lint-baseline.txt through to droidstubs.
  1451. baselinePath := path.Join(apiDir, apiScope.apiFilePrefix+"lint-baseline.txt")
  1452. baselinePathRelativeToRoot := path.Join(mctx.ModuleDir(), baselinePath)
  1453. paths, err := mctx.GlobWithDeps(baselinePathRelativeToRoot, nil)
  1454. if err != nil {
  1455. mctx.ModuleErrorf("error checking for presence of %s: %s", baselinePathRelativeToRoot, err)
  1456. }
  1457. if len(paths) == 1 {
  1458. props.Check_api.Api_lint.Baseline_file = proptools.StringPtr(baselinePath)
  1459. } else if len(paths) != 0 {
  1460. mctx.ModuleErrorf("error checking for presence of %s: expected one path, found: %v", baselinePathRelativeToRoot, paths)
  1461. }
  1462. }
  1463. }
  1464. if !Bool(module.sdkLibraryProperties.No_dist) {
  1465. // Dist the api txt and removed api txt artifacts for sdk builds.
  1466. distDir := proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
  1467. for _, p := range []struct {
  1468. tag string
  1469. pattern string
  1470. }{
  1471. {tag: ".api.txt", pattern: "%s.txt"},
  1472. {tag: ".removed-api.txt", pattern: "%s-removed.txt"},
  1473. } {
  1474. props.Dists = append(props.Dists, android.Dist{
  1475. Targets: []string{"sdk", "win_sdk"},
  1476. Dir: distDir,
  1477. Dest: proptools.StringPtr(fmt.Sprintf(p.pattern, module.distStem())),
  1478. Tag: proptools.StringPtr(p.tag),
  1479. })
  1480. }
  1481. }
  1482. mctx.CreateModule(DroidstubsFactory, &props)
  1483. }
  1484. func (module *SdkLibrary) compareAgainstLatestApi(apiScope *apiScope) bool {
  1485. return !(apiScope.unstable || module.sdkLibraryProperties.Unsafe_ignore_missing_latest_api)
  1486. }
  1487. // Implements android.ApexModule
  1488. func (module *SdkLibrary) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
  1489. depTag := mctx.OtherModuleDependencyTag(dep)
  1490. if depTag == xmlPermissionsFileTag {
  1491. return true
  1492. }
  1493. return module.Library.DepIsInSameApex(mctx, dep)
  1494. }
  1495. // Implements android.ApexModule
  1496. func (module *SdkLibrary) UniqueApexVariations() bool {
  1497. return module.uniqueApexVariations()
  1498. }
  1499. // Creates the xml file that publicizes the runtime library
  1500. func (module *SdkLibrary) createXmlFile(mctx android.DefaultableHookContext) {
  1501. moduleMinApiLevel := module.Library.MinSdkVersion(mctx).ApiLevel
  1502. var moduleMinApiLevelStr = moduleMinApiLevel.String()
  1503. if moduleMinApiLevel == android.NoneApiLevel {
  1504. moduleMinApiLevelStr = "current"
  1505. }
  1506. props := struct {
  1507. Name *string
  1508. Lib_name *string
  1509. Apex_available []string
  1510. On_bootclasspath_since *string
  1511. On_bootclasspath_before *string
  1512. Min_device_sdk *string
  1513. Max_device_sdk *string
  1514. Sdk_library_min_api_level *string
  1515. }{
  1516. Name: proptools.StringPtr(module.xmlPermissionsModuleName()),
  1517. Lib_name: proptools.StringPtr(module.BaseModuleName()),
  1518. Apex_available: module.ApexProperties.Apex_available,
  1519. On_bootclasspath_since: module.commonSdkLibraryProperties.On_bootclasspath_since,
  1520. On_bootclasspath_before: module.commonSdkLibraryProperties.On_bootclasspath_before,
  1521. Min_device_sdk: module.commonSdkLibraryProperties.Min_device_sdk,
  1522. Max_device_sdk: module.commonSdkLibraryProperties.Max_device_sdk,
  1523. Sdk_library_min_api_level: &moduleMinApiLevelStr,
  1524. }
  1525. mctx.CreateModule(sdkLibraryXmlFactory, &props)
  1526. }
  1527. func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s android.SdkSpec) android.Paths {
  1528. var ver android.ApiLevel
  1529. var kind android.SdkKind
  1530. if s.UsePrebuilt(ctx) {
  1531. ver = s.ApiLevel
  1532. kind = s.Kind
  1533. } else {
  1534. // We don't have prebuilt SDK for the specific sdkVersion.
  1535. // Instead of breaking the build, fallback to use "system_current"
  1536. ver = android.FutureApiLevel
  1537. kind = android.SdkSystem
  1538. }
  1539. dir := filepath.Join("prebuilts", "sdk", ver.String(), kind.String())
  1540. jar := filepath.Join(dir, baseName+".jar")
  1541. jarPath := android.ExistentPathForSource(ctx, jar)
  1542. if !jarPath.Valid() {
  1543. if ctx.Config().AllowMissingDependencies() {
  1544. return android.Paths{android.PathForSource(ctx, jar)}
  1545. } else {
  1546. ctx.PropertyErrorf("sdk_library", "invalid sdk version %q, %q does not exist", s.Raw, jar)
  1547. }
  1548. return nil
  1549. }
  1550. return android.Paths{jarPath.Path()}
  1551. }
  1552. // Check to see if the other module is within the same set of named APEXes as this module.
  1553. //
  1554. // If either this or the other module are on the platform then this will return
  1555. // false.
  1556. func withinSameApexesAs(ctx android.BaseModuleContext, other android.Module) bool {
  1557. apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
  1558. otherApexInfo := ctx.OtherModuleProvider(other, android.ApexInfoProvider).(android.ApexInfo)
  1559. return len(otherApexInfo.InApexVariants) > 0 && reflect.DeepEqual(apexInfo.InApexVariants, otherApexInfo.InApexVariants)
  1560. }
  1561. func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths {
  1562. // If the client doesn't set sdk_version, but if this library prefers stubs over
  1563. // the impl library, let's provide the widest API surface possible. To do so,
  1564. // force override sdk_version to module_current so that the closest possible API
  1565. // surface could be found in selectHeaderJarsForSdkVersion
  1566. if module.defaultsToStubs() && !sdkVersion.Specified() {
  1567. sdkVersion = android.SdkSpecFrom(ctx, "module_current")
  1568. }
  1569. // Only provide access to the implementation library if it is actually built.
  1570. if module.requiresRuntimeImplementationLibrary() {
  1571. // Check any special cases for java_sdk_library.
  1572. //
  1573. // Only allow access to the implementation library in the following condition:
  1574. // * No sdk_version specified on the referencing module.
  1575. // * The referencing module is in the same apex as this.
  1576. if sdkVersion.Kind == android.SdkPrivate || withinSameApexesAs(ctx, module) {
  1577. if headerJars {
  1578. return module.HeaderJars()
  1579. } else {
  1580. return module.ImplementationJars()
  1581. }
  1582. }
  1583. }
  1584. return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
  1585. }
  1586. // to satisfy SdkLibraryDependency interface
  1587. func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
  1588. return module.sdkJars(ctx, sdkVersion, true /*headerJars*/)
  1589. }
  1590. // to satisfy SdkLibraryDependency interface
  1591. func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
  1592. return module.sdkJars(ctx, sdkVersion, false /*headerJars*/)
  1593. }
  1594. var javaSdkLibrariesKey = android.NewOnceKey("javaSdkLibraries")
  1595. func javaSdkLibraries(config android.Config) *[]string {
  1596. return config.Once(javaSdkLibrariesKey, func() interface{} {
  1597. return &[]string{}
  1598. }).(*[]string)
  1599. }
  1600. func (module *SdkLibrary) getApiDir() string {
  1601. return proptools.StringDefault(module.sdkLibraryProperties.Api_dir, "api")
  1602. }
  1603. // For a java_sdk_library module, create internal modules for stubs, docs,
  1604. // runtime libs and xml file. If requested, the stubs and docs are created twice
  1605. // once for public API level and once for system API level
  1606. func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookContext) {
  1607. // If the module has been disabled then don't create any child modules.
  1608. if !module.Enabled() {
  1609. return
  1610. }
  1611. if len(module.properties.Srcs) == 0 {
  1612. mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
  1613. return
  1614. }
  1615. // If this builds against standard libraries (i.e. is not part of the core libraries)
  1616. // then assume it provides both system and test apis.
  1617. sdkDep := decodeSdkDep(mctx, android.SdkContext(&module.Library))
  1618. hasSystemAndTestApis := sdkDep.hasStandardLibs()
  1619. module.sdkLibraryProperties.Generate_system_and_test_apis = hasSystemAndTestApis
  1620. missingCurrentApi := false
  1621. generatedScopes := module.getGeneratedApiScopes(mctx)
  1622. apiDir := module.getApiDir()
  1623. for _, scope := range generatedScopes {
  1624. for _, api := range []string{"current.txt", "removed.txt"} {
  1625. path := path.Join(mctx.ModuleDir(), apiDir, scope.apiFilePrefix+api)
  1626. p := android.ExistentPathForSource(mctx, path)
  1627. if !p.Valid() {
  1628. if mctx.Config().AllowMissingDependencies() {
  1629. mctx.AddMissingDependencies([]string{path})
  1630. } else {
  1631. mctx.ModuleErrorf("Current api file %#v doesn't exist", path)
  1632. missingCurrentApi = true
  1633. }
  1634. }
  1635. }
  1636. }
  1637. if missingCurrentApi {
  1638. script := "build/soong/scripts/gen-java-current-api-files.sh"
  1639. p := android.ExistentPathForSource(mctx, script)
  1640. if !p.Valid() {
  1641. panic(fmt.Sprintf("script file %s doesn't exist", script))
  1642. }
  1643. mctx.ModuleErrorf("One or more current api files are missing. "+
  1644. "You can update them by:\n"+
  1645. "%s %q %s && m update-api",
  1646. script, filepath.Join(mctx.ModuleDir(), apiDir),
  1647. strings.Join(generatedScopes.Strings(func(s *apiScope) string { return s.apiFilePrefix }), " "))
  1648. return
  1649. }
  1650. for _, scope := range generatedScopes {
  1651. // Use the stubs source name for legacy reasons.
  1652. module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)
  1653. module.createStubsLibrary(mctx, scope)
  1654. }
  1655. if module.requiresRuntimeImplementationLibrary() {
  1656. // Create child module to create an implementation library.
  1657. //
  1658. // This temporarily creates a second implementation library that can be explicitly
  1659. // referenced.
  1660. //
  1661. // TODO(b/156618935) - update comment once only one implementation library is created.
  1662. module.createImplLibrary(mctx)
  1663. // Only create an XML permissions file that declares the library as being usable
  1664. // as a shared library if required.
  1665. if module.sharedLibrary() {
  1666. module.createXmlFile(mctx)
  1667. }
  1668. // record java_sdk_library modules so that they are exported to make
  1669. javaSdkLibraries := javaSdkLibraries(mctx.Config())
  1670. javaSdkLibrariesLock.Lock()
  1671. defer javaSdkLibrariesLock.Unlock()
  1672. *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
  1673. }
  1674. // Add the impl_only_libs and impl_only_static_libs *after* we're done using them in submodules.
  1675. module.properties.Libs = append(module.properties.Libs, module.sdkLibraryProperties.Impl_only_libs...)
  1676. module.properties.Static_libs = append(module.properties.Static_libs, module.sdkLibraryProperties.Impl_only_static_libs...)
  1677. }
  1678. func (module *SdkLibrary) InitSdkLibraryProperties() {
  1679. module.addHostAndDeviceProperties()
  1680. module.AddProperties(&module.sdkLibraryProperties)
  1681. module.initSdkLibraryComponent(module)
  1682. module.properties.Installable = proptools.BoolPtr(true)
  1683. module.deviceProperties.IsSDKLibrary = true
  1684. }
  1685. func (module *SdkLibrary) requiresRuntimeImplementationLibrary() bool {
  1686. return !proptools.Bool(module.sdkLibraryProperties.Api_only)
  1687. }
  1688. func (module *SdkLibrary) defaultsToStubs() bool {
  1689. return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs)
  1690. }
  1691. // Defines how to name the individual component modules the sdk library creates.
  1692. type sdkLibraryComponentNamingScheme interface {
  1693. stubsLibraryModuleName(scope *apiScope, baseName string) string
  1694. stubsSourceModuleName(scope *apiScope, baseName string) string
  1695. }
  1696. type defaultNamingScheme struct {
  1697. }
  1698. func (s *defaultNamingScheme) stubsLibraryModuleName(scope *apiScope, baseName string) string {
  1699. return scope.stubsLibraryModuleName(baseName)
  1700. }
  1701. func (s *defaultNamingScheme) stubsSourceModuleName(scope *apiScope, baseName string) string {
  1702. return scope.stubsSourceModuleName(baseName)
  1703. }
  1704. var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
  1705. func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) {
  1706. // This suffix-based approach is fragile and could potentially mis-trigger.
  1707. // TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
  1708. if strings.HasSuffix(name, apiScopePublic.stubsLibraryModuleNameSuffix()) {
  1709. if name == "hwbinder.stubs" || name == "libcore_private.stubs" {
  1710. // Due to a previous bug, these modules were not considered stubs, so we retain that.
  1711. return false, javaPlatform
  1712. }
  1713. return true, javaSdk
  1714. }
  1715. if strings.HasSuffix(name, apiScopeSystem.stubsLibraryModuleNameSuffix()) {
  1716. return true, javaSystem
  1717. }
  1718. if strings.HasSuffix(name, apiScopeModuleLib.stubsLibraryModuleNameSuffix()) {
  1719. return true, javaModule
  1720. }
  1721. if strings.HasSuffix(name, apiScopeTest.stubsLibraryModuleNameSuffix()) {
  1722. return true, javaSystem
  1723. }
  1724. return false, javaPlatform
  1725. }
  1726. // java_sdk_library is a special Java library that provides optional platform APIs to apps.
  1727. // In practice, it can be viewed as a combination of several modules: 1) stubs library that clients
  1728. // are linked against to, 2) droiddoc module that internally generates API stubs source files,
  1729. // 3) the real runtime shared library that implements the APIs, and 4) XML file for adding
  1730. // the runtime lib to the classpath at runtime if requested via <uses-library>.
  1731. func SdkLibraryFactory() android.Module {
  1732. module := &SdkLibrary{}
  1733. // Initialize information common between source and prebuilt.
  1734. module.initCommon(module)
  1735. module.InitSdkLibraryProperties()
  1736. android.InitApexModule(module)
  1737. InitJavaModule(module, android.HostAndDeviceSupported)
  1738. // Initialize the map from scope to scope specific properties.
  1739. scopeToProperties := make(map[*apiScope]*ApiScopeProperties)
  1740. for _, scope := range allApiScopes {
  1741. scopeToProperties[scope] = scope.scopeSpecificProperties(module)
  1742. }
  1743. module.scopeToProperties = scopeToProperties
  1744. // Add the properties containing visibility rules so that they are checked.
  1745. android.AddVisibilityProperty(module, "impl_library_visibility", &module.sdkLibraryProperties.Impl_library_visibility)
  1746. android.AddVisibilityProperty(module, "stubs_library_visibility", &module.sdkLibraryProperties.Stubs_library_visibility)
  1747. android.AddVisibilityProperty(module, "stubs_source_visibility", &module.sdkLibraryProperties.Stubs_source_visibility)
  1748. module.SetDefaultableHook(func(ctx android.DefaultableHookContext) {
  1749. // If no implementation is required then it cannot be used as a shared library
  1750. // either.
  1751. if !module.requiresRuntimeImplementationLibrary() {
  1752. // If shared_library has been explicitly set to true then it is incompatible
  1753. // with api_only: true.
  1754. if proptools.Bool(module.commonSdkLibraryProperties.Shared_library) {
  1755. ctx.PropertyErrorf("api_only/shared_library", "inconsistent settings, shared_library and api_only cannot both be true")
  1756. }
  1757. // Set shared_library: false.
  1758. module.commonSdkLibraryProperties.Shared_library = proptools.BoolPtr(false)
  1759. }
  1760. if module.initCommonAfterDefaultsApplied(ctx) {
  1761. module.CreateInternalModules(ctx)
  1762. }
  1763. })
  1764. return module
  1765. }
  1766. //
  1767. // SDK library prebuilts
  1768. //
  1769. // Properties associated with each api scope.
  1770. type sdkLibraryScopeProperties struct {
  1771. Jars []string `android:"path"`
  1772. Sdk_version *string
  1773. // List of shared java libs that this module has dependencies to
  1774. Libs []string
  1775. // The stubs source.
  1776. Stub_srcs []string `android:"path"`
  1777. // The current.txt
  1778. Current_api *string `android:"path"`
  1779. // The removed.txt
  1780. Removed_api *string `android:"path"`
  1781. // Annotation zip
  1782. Annotations *string `android:"path"`
  1783. }
  1784. type sdkLibraryImportProperties struct {
  1785. // List of shared java libs, common to all scopes, that this module has
  1786. // dependencies to
  1787. Libs []string
  1788. // If set to true, compile dex files for the stubs. Defaults to false.
  1789. Compile_dex *bool
  1790. // If not empty, classes are restricted to the specified packages and their sub-packages.
  1791. Permitted_packages []string
  1792. }
  1793. type SdkLibraryImport struct {
  1794. android.ModuleBase
  1795. android.DefaultableModuleBase
  1796. prebuilt android.Prebuilt
  1797. android.ApexModuleBase
  1798. hiddenAPI
  1799. dexpreopter
  1800. properties sdkLibraryImportProperties
  1801. // Map from api scope to the scope specific property structure.
  1802. scopeProperties map[*apiScope]*sdkLibraryScopeProperties
  1803. commonToSdkLibraryAndImport
  1804. // The reference to the implementation library created by the source module.
  1805. // Is nil if the source module does not exist.
  1806. implLibraryModule *Library
  1807. // The reference to the xml permissions module created by the source module.
  1808. // Is nil if the source module does not exist.
  1809. xmlPermissionsFileModule *sdkLibraryXml
  1810. // Build path to the dex implementation jar obtained from the prebuilt_apex, if any.
  1811. dexJarFile OptionalDexJarPath
  1812. // Expected install file path of the source module(sdk_library)
  1813. // or dex implementation jar obtained from the prebuilt_apex, if any.
  1814. installFile android.Path
  1815. }
  1816. var _ SdkLibraryDependency = (*SdkLibraryImport)(nil)
  1817. // The type of a structure that contains a field of type sdkLibraryScopeProperties
  1818. // for each apiscope in allApiScopes, e.g. something like:
  1819. //
  1820. // struct {
  1821. // Public sdkLibraryScopeProperties
  1822. // System sdkLibraryScopeProperties
  1823. // ...
  1824. // }
  1825. var allScopeStructType = createAllScopePropertiesStructType()
  1826. // Dynamically create a structure type for each apiscope in allApiScopes.
  1827. func createAllScopePropertiesStructType() reflect.Type {
  1828. var fields []reflect.StructField
  1829. for _, apiScope := range allApiScopes {
  1830. field := reflect.StructField{
  1831. Name: apiScope.fieldName,
  1832. Type: reflect.TypeOf(sdkLibraryScopeProperties{}),
  1833. }
  1834. fields = append(fields, field)
  1835. }
  1836. return reflect.StructOf(fields)
  1837. }
  1838. // Create an instance of the scope specific structure type and return a map
  1839. // from apiscope to a pointer to each scope specific field.
  1840. func createPropertiesInstance() (interface{}, map[*apiScope]*sdkLibraryScopeProperties) {
  1841. allScopePropertiesPtr := reflect.New(allScopeStructType)
  1842. allScopePropertiesStruct := allScopePropertiesPtr.Elem()
  1843. scopeProperties := make(map[*apiScope]*sdkLibraryScopeProperties)
  1844. for _, apiScope := range allApiScopes {
  1845. field := allScopePropertiesStruct.FieldByName(apiScope.fieldName)
  1846. scopeProperties[apiScope] = field.Addr().Interface().(*sdkLibraryScopeProperties)
  1847. }
  1848. return allScopePropertiesPtr.Interface(), scopeProperties
  1849. }
  1850. // java_sdk_library_import imports a prebuilt java_sdk_library.
  1851. func sdkLibraryImportFactory() android.Module {
  1852. module := &SdkLibraryImport{}
  1853. allScopeProperties, scopeToProperties := createPropertiesInstance()
  1854. module.scopeProperties = scopeToProperties
  1855. module.AddProperties(&module.properties, allScopeProperties)
  1856. // Initialize information common between source and prebuilt.
  1857. module.initCommon(module)
  1858. android.InitPrebuiltModule(module, &[]string{""})
  1859. android.InitApexModule(module)
  1860. InitJavaModule(module, android.HostAndDeviceSupported)
  1861. module.SetDefaultableHook(func(mctx android.DefaultableHookContext) {
  1862. if module.initCommonAfterDefaultsApplied(mctx) {
  1863. module.createInternalModules(mctx)
  1864. }
  1865. })
  1866. return module
  1867. }
  1868. var _ PermittedPackagesForUpdatableBootJars = (*SdkLibraryImport)(nil)
  1869. func (module *SdkLibraryImport) PermittedPackagesForUpdatableBootJars() []string {
  1870. return module.properties.Permitted_packages
  1871. }
  1872. func (module *SdkLibraryImport) Prebuilt() *android.Prebuilt {
  1873. return &module.prebuilt
  1874. }
  1875. func (module *SdkLibraryImport) Name() string {
  1876. return module.prebuilt.Name(module.ModuleBase.Name())
  1877. }
  1878. func (module *SdkLibraryImport) createInternalModules(mctx android.DefaultableHookContext) {
  1879. // If the build is configured to use prebuilts then force this to be preferred.
  1880. if mctx.Config().AlwaysUsePrebuiltSdks() {
  1881. module.prebuilt.ForcePrefer()
  1882. }
  1883. for apiScope, scopeProperties := range module.scopeProperties {
  1884. if len(scopeProperties.Jars) == 0 {
  1885. continue
  1886. }
  1887. module.createJavaImportForStubs(mctx, apiScope, scopeProperties)
  1888. if len(scopeProperties.Stub_srcs) > 0 {
  1889. module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
  1890. }
  1891. }
  1892. javaSdkLibraries := javaSdkLibraries(mctx.Config())
  1893. javaSdkLibrariesLock.Lock()
  1894. defer javaSdkLibrariesLock.Unlock()
  1895. *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
  1896. }
  1897. func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
  1898. // Creates a java import for the jar with ".stubs" suffix
  1899. props := struct {
  1900. Name *string
  1901. Sdk_version *string
  1902. Libs []string
  1903. Jars []string
  1904. Compile_dex *bool
  1905. android.UserSuppliedPrebuiltProperties
  1906. }{}
  1907. props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
  1908. props.Sdk_version = scopeProperties.Sdk_version
  1909. // Prepend any of the libs from the legacy public properties to the libs for each of the
  1910. // scopes to avoid having to duplicate them in each scope.
  1911. props.Libs = append(module.properties.Libs, scopeProperties.Libs...)
  1912. props.Jars = scopeProperties.Jars
  1913. // The imports are preferred if the java_sdk_library_import is preferred.
  1914. props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
  1915. // The imports need to be compiled to dex if the java_sdk_library_import requests it.
  1916. compileDex := module.properties.Compile_dex
  1917. if module.stubLibrariesCompiledForDex() {
  1918. compileDex = proptools.BoolPtr(true)
  1919. }
  1920. props.Compile_dex = compileDex
  1921. mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
  1922. }
  1923. func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
  1924. props := struct {
  1925. Name *string
  1926. Srcs []string
  1927. android.UserSuppliedPrebuiltProperties
  1928. }{}
  1929. props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope))
  1930. props.Srcs = scopeProperties.Stub_srcs
  1931. // The stubs source is preferred if the java_sdk_library_import is preferred.
  1932. props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt)
  1933. mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
  1934. }
  1935. // Add the dependencies on the child module in the component deps mutator so that it
  1936. // creates references to the prebuilt and not the source modules.
  1937. func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
  1938. for apiScope, scopeProperties := range module.scopeProperties {
  1939. if len(scopeProperties.Jars) == 0 {
  1940. continue
  1941. }
  1942. // Add dependencies to the prebuilt stubs library
  1943. ctx.AddVariationDependencies(nil, apiScope.stubsTag, android.PrebuiltNameFromSource(module.stubsLibraryModuleName(apiScope)))
  1944. if len(scopeProperties.Stub_srcs) > 0 {
  1945. // Add dependencies to the prebuilt stubs source library
  1946. ctx.AddVariationDependencies(nil, apiScope.stubsSourceTag, android.PrebuiltNameFromSource(module.stubsSourceModuleName(apiScope)))
  1947. }
  1948. }
  1949. }
  1950. // Add other dependencies as normal.
  1951. func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) {
  1952. implName := module.implLibraryModuleName()
  1953. if ctx.OtherModuleExists(implName) {
  1954. ctx.AddVariationDependencies(nil, implLibraryTag, implName)
  1955. xmlPermissionsModuleName := module.xmlPermissionsModuleName()
  1956. if module.sharedLibrary() && ctx.OtherModuleExists(xmlPermissionsModuleName) {
  1957. // Add dependency to the rule for generating the xml permissions file
  1958. ctx.AddDependency(module, xmlPermissionsFileTag, xmlPermissionsModuleName)
  1959. }
  1960. }
  1961. }
  1962. func (module *SdkLibraryImport) AndroidMkEntries() []android.AndroidMkEntries {
  1963. // For an SDK library imported from a prebuilt APEX, we don't need a Make module for itself, as we
  1964. // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it
  1965. // is preopted.
  1966. dexpreoptEntries := module.dexpreopter.AndroidMkEntriesForApex()
  1967. return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true})
  1968. }
  1969. var _ android.ApexModule = (*SdkLibraryImport)(nil)
  1970. // Implements android.ApexModule
  1971. func (module *SdkLibraryImport) DepIsInSameApex(mctx android.BaseModuleContext, dep android.Module) bool {
  1972. depTag := mctx.OtherModuleDependencyTag(dep)
  1973. if depTag == xmlPermissionsFileTag {
  1974. return true
  1975. }
  1976. // None of the other dependencies of the java_sdk_library_import are in the same apex
  1977. // as the one that references this module.
  1978. return false
  1979. }
  1980. // Implements android.ApexModule
  1981. func (module *SdkLibraryImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
  1982. sdkVersion android.ApiLevel) error {
  1983. // we don't check prebuilt modules for sdk_version
  1984. return nil
  1985. }
  1986. // Implements android.ApexModule
  1987. func (module *SdkLibraryImport) UniqueApexVariations() bool {
  1988. return module.uniqueApexVariations()
  1989. }
  1990. // MinSdkVersion - Implements hiddenAPIModule
  1991. func (module *SdkLibraryImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
  1992. return android.SdkSpecNone
  1993. }
  1994. var _ hiddenAPIModule = (*SdkLibraryImport)(nil)
  1995. func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
  1996. paths, err := module.commonOutputFiles(tag)
  1997. if paths != nil || err != nil {
  1998. return paths, err
  1999. }
  2000. if module.implLibraryModule != nil {
  2001. return module.implLibraryModule.OutputFiles(tag)
  2002. } else {
  2003. return nil, nil
  2004. }
  2005. }
  2006. func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  2007. module.generateCommonBuildActions(ctx)
  2008. // Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework
  2009. module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar")
  2010. // Record the paths to the prebuilt stubs library and stubs source.
  2011. ctx.VisitDirectDeps(func(to android.Module) {
  2012. tag := ctx.OtherModuleDependencyTag(to)
  2013. // Extract information from any of the scope specific dependencies.
  2014. if scopeTag, ok := tag.(scopeDependencyTag); ok {
  2015. apiScope := scopeTag.apiScope
  2016. scopePaths := module.getScopePathsCreateIfNeeded(apiScope)
  2017. // Extract information from the dependency. The exact information extracted
  2018. // is determined by the nature of the dependency which is determined by the tag.
  2019. scopeTag.extractDepInfo(ctx, to, scopePaths)
  2020. } else if tag == implLibraryTag {
  2021. if implLibrary, ok := to.(*Library); ok {
  2022. module.implLibraryModule = implLibrary
  2023. } else {
  2024. ctx.ModuleErrorf("implementation library must be of type *java.Library but was %T", to)
  2025. }
  2026. } else if tag == xmlPermissionsFileTag {
  2027. if xmlPermissionsFileModule, ok := to.(*sdkLibraryXml); ok {
  2028. module.xmlPermissionsFileModule = xmlPermissionsFileModule
  2029. } else {
  2030. ctx.ModuleErrorf("xml permissions file module must be of type *sdkLibraryXml but was %T", to)
  2031. }
  2032. }
  2033. })
  2034. // Populate the scope paths with information from the properties.
  2035. for apiScope, scopeProperties := range module.scopeProperties {
  2036. if len(scopeProperties.Jars) == 0 {
  2037. continue
  2038. }
  2039. paths := module.getScopePathsCreateIfNeeded(apiScope)
  2040. paths.annotationsZip = android.OptionalPathForModuleSrc(ctx, scopeProperties.Annotations)
  2041. paths.currentApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Current_api)
  2042. paths.removedApiFilePath = android.OptionalPathForModuleSrc(ctx, scopeProperties.Removed_api)
  2043. }
  2044. if ctx.Device() {
  2045. // If this is a variant created for a prebuilt_apex then use the dex implementation jar
  2046. // obtained from the associated deapexer module.
  2047. ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
  2048. if ai.ForPrebuiltApex {
  2049. // Get the path of the dex implementation jar from the `deapexer` module.
  2050. di := android.FindDeapexerProviderForModule(ctx)
  2051. if di == nil {
  2052. return // An error has been reported by FindDeapexerProviderForModule.
  2053. }
  2054. if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil {
  2055. dexJarFile := makeDexJarPathFromPath(dexOutputPath)
  2056. module.dexJarFile = dexJarFile
  2057. installPath := android.PathForModuleInPartitionInstall(
  2058. ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName()))
  2059. module.installFile = installPath
  2060. module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
  2061. // Dexpreopting.
  2062. module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, installPath)
  2063. module.dexpreopter.isSDKLibrary = true
  2064. module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &module.dexpreopter)
  2065. module.dexpreopt(ctx, dexOutputPath)
  2066. } else {
  2067. // This should never happen as a variant for a prebuilt_apex is only created if the
  2068. // prebuilt_apex has been configured to export the java library dex file.
  2069. ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName())
  2070. }
  2071. }
  2072. }
  2073. }
  2074. func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths {
  2075. // For consistency with SdkLibrary make the implementation jar available to libraries that
  2076. // are within the same APEX.
  2077. implLibraryModule := module.implLibraryModule
  2078. if implLibraryModule != nil && withinSameApexesAs(ctx, module) {
  2079. if headerJars {
  2080. return implLibraryModule.HeaderJars()
  2081. } else {
  2082. return implLibraryModule.ImplementationJars()
  2083. }
  2084. }
  2085. return module.selectHeaderJarsForSdkVersion(ctx, sdkVersion)
  2086. }
  2087. // to satisfy SdkLibraryDependency interface
  2088. func (module *SdkLibraryImport) SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
  2089. // This module is just a wrapper for the prebuilt stubs.
  2090. return module.sdkJars(ctx, sdkVersion, true)
  2091. }
  2092. // to satisfy SdkLibraryDependency interface
  2093. func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec) android.Paths {
  2094. // This module is just a wrapper for the stubs.
  2095. return module.sdkJars(ctx, sdkVersion, false)
  2096. }
  2097. // to satisfy UsesLibraryDependency interface
  2098. func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath {
  2099. // The dex implementation jar extracted from the .apex file should be used in preference to the
  2100. // source.
  2101. if module.dexJarFile.IsSet() {
  2102. return module.dexJarFile
  2103. }
  2104. if module.implLibraryModule == nil {
  2105. return makeUnsetDexJarPath()
  2106. } else {
  2107. return module.implLibraryModule.DexJarBuildPath()
  2108. }
  2109. }
  2110. // to satisfy UsesLibraryDependency interface
  2111. func (module *SdkLibraryImport) DexJarInstallPath() android.Path {
  2112. return module.installFile
  2113. }
  2114. // to satisfy UsesLibraryDependency interface
  2115. func (module *SdkLibraryImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap {
  2116. return nil
  2117. }
  2118. // to satisfy apex.javaDependency interface
  2119. func (module *SdkLibraryImport) JacocoReportClassesFile() android.Path {
  2120. if module.implLibraryModule == nil {
  2121. return nil
  2122. } else {
  2123. return module.implLibraryModule.JacocoReportClassesFile()
  2124. }
  2125. }
  2126. // to satisfy apex.javaDependency interface
  2127. func (module *SdkLibraryImport) LintDepSets() LintDepSets {
  2128. if module.implLibraryModule == nil {
  2129. return LintDepSets{}
  2130. } else {
  2131. return module.implLibraryModule.LintDepSets()
  2132. }
  2133. }
  2134. func (module *SdkLibraryImport) GetStrictUpdatabilityLinting() bool {
  2135. if module.implLibraryModule == nil {
  2136. return false
  2137. } else {
  2138. return module.implLibraryModule.GetStrictUpdatabilityLinting()
  2139. }
  2140. }
  2141. func (module *SdkLibraryImport) SetStrictUpdatabilityLinting(strictLinting bool) {
  2142. if module.implLibraryModule != nil {
  2143. module.implLibraryModule.SetStrictUpdatabilityLinting(strictLinting)
  2144. }
  2145. }
  2146. // to satisfy apex.javaDependency interface
  2147. func (module *SdkLibraryImport) Stem() string {
  2148. return module.BaseModuleName()
  2149. }
  2150. var _ ApexDependency = (*SdkLibraryImport)(nil)
  2151. // to satisfy java.ApexDependency interface
  2152. func (module *SdkLibraryImport) HeaderJars() android.Paths {
  2153. if module.implLibraryModule == nil {
  2154. return nil
  2155. } else {
  2156. return module.implLibraryModule.HeaderJars()
  2157. }
  2158. }
  2159. // to satisfy java.ApexDependency interface
  2160. func (module *SdkLibraryImport) ImplementationAndResourcesJars() android.Paths {
  2161. if module.implLibraryModule == nil {
  2162. return nil
  2163. } else {
  2164. return module.implLibraryModule.ImplementationAndResourcesJars()
  2165. }
  2166. }
  2167. // to satisfy java.DexpreopterInterface interface
  2168. func (module *SdkLibraryImport) IsInstallable() bool {
  2169. return true
  2170. }
  2171. var _ android.RequiredFilesFromPrebuiltApex = (*SdkLibraryImport)(nil)
  2172. func (module *SdkLibraryImport) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string {
  2173. name := module.BaseModuleName()
  2174. return requiredFilesFromPrebuiltApexForImport(name)
  2175. }
  2176. // java_sdk_library_xml
  2177. type sdkLibraryXml struct {
  2178. android.ModuleBase
  2179. android.DefaultableModuleBase
  2180. android.ApexModuleBase
  2181. properties sdkLibraryXmlProperties
  2182. outputFilePath android.OutputPath
  2183. installDirPath android.InstallPath
  2184. hideApexVariantFromMake bool
  2185. }
  2186. type sdkLibraryXmlProperties struct {
  2187. // canonical name of the lib
  2188. Lib_name *string
  2189. // Signals that this shared library is part of the bootclasspath starting
  2190. // on the version indicated in this attribute.
  2191. //
  2192. // This will make platforms at this level and above to ignore
  2193. // <uses-library> tags with this library name because the library is already
  2194. // available
  2195. On_bootclasspath_since *string
  2196. // Signals that this shared library was part of the bootclasspath before
  2197. // (but not including) the version indicated in this attribute.
  2198. //
  2199. // The system will automatically add a <uses-library> tag with this library to
  2200. // apps that target any SDK less than the version indicated in this attribute.
  2201. On_bootclasspath_before *string
  2202. // Indicates that PackageManager should ignore this shared library if the
  2203. // platform is below the version indicated in this attribute.
  2204. //
  2205. // This means that the device won't recognise this library as installed.
  2206. Min_device_sdk *string
  2207. // Indicates that PackageManager should ignore this shared library if the
  2208. // platform is above the version indicated in this attribute.
  2209. //
  2210. // This means that the device won't recognise this library as installed.
  2211. Max_device_sdk *string
  2212. // The SdkLibrary's min api level as a string
  2213. //
  2214. // This value comes from the ApiLevel of the MinSdkVersion property.
  2215. Sdk_library_min_api_level *string
  2216. }
  2217. // java_sdk_library_xml builds the permission xml file for a java_sdk_library.
  2218. // Not to be used directly by users. java_sdk_library internally uses this.
  2219. func sdkLibraryXmlFactory() android.Module {
  2220. module := &sdkLibraryXml{}
  2221. module.AddProperties(&module.properties)
  2222. android.InitApexModule(module)
  2223. android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
  2224. return module
  2225. }
  2226. func (module *sdkLibraryXml) UniqueApexVariations() bool {
  2227. // sdkLibraryXml needs a unique variation per APEX because the generated XML file contains the path to the
  2228. // mounted APEX, which contains the name of the APEX.
  2229. return true
  2230. }
  2231. // from android.PrebuiltEtcModule
  2232. func (module *sdkLibraryXml) BaseDir() string {
  2233. return "etc"
  2234. }
  2235. // from android.PrebuiltEtcModule
  2236. func (module *sdkLibraryXml) SubDir() string {
  2237. return "permissions"
  2238. }
  2239. // from android.PrebuiltEtcModule
  2240. func (module *sdkLibraryXml) OutputFile() android.OutputPath {
  2241. return module.outputFilePath
  2242. }
  2243. // from android.ApexModule
  2244. func (module *sdkLibraryXml) AvailableFor(what string) bool {
  2245. return true
  2246. }
  2247. func (module *sdkLibraryXml) DepsMutator(ctx android.BottomUpMutatorContext) {
  2248. // do nothing
  2249. }
  2250. var _ android.ApexModule = (*sdkLibraryXml)(nil)
  2251. // Implements android.ApexModule
  2252. func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleContext,
  2253. sdkVersion android.ApiLevel) error {
  2254. // sdkLibraryXml doesn't need to be checked separately because java_sdk_library is checked
  2255. return nil
  2256. }
  2257. // File path to the runtime implementation library
  2258. func (module *sdkLibraryXml) implPath(ctx android.ModuleContext) string {
  2259. implName := proptools.String(module.properties.Lib_name)
  2260. if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() {
  2261. // TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name.
  2262. // In most cases, this works fine. But when apex_name is set or override_apex is used
  2263. // this can be wrong.
  2264. return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexInfo.ApexVariationName, implName)
  2265. }
  2266. partition := "system"
  2267. if module.SocSpecific() {
  2268. partition = "vendor"
  2269. } else if module.DeviceSpecific() {
  2270. partition = "odm"
  2271. } else if module.ProductSpecific() {
  2272. partition = "product"
  2273. } else if module.SystemExtSpecific() {
  2274. partition = "system_ext"
  2275. }
  2276. return "/" + partition + "/framework/" + implName + ".jar"
  2277. }
  2278. func formattedOptionalSdkLevelAttribute(ctx android.ModuleContext, attrName string, value *string) string {
  2279. if value == nil {
  2280. return ""
  2281. }
  2282. apiLevel, err := android.ApiLevelFromUser(ctx, *value)
  2283. if err != nil {
  2284. // attributes in bp files have underscores but in the xml have dashes.
  2285. ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"), err.Error())
  2286. return ""
  2287. }
  2288. if apiLevel.IsCurrent() {
  2289. // passing "current" would always mean a future release, never the current (or the current in
  2290. // progress) which means some conditions would never be triggered.
  2291. ctx.PropertyErrorf(strings.ReplaceAll(attrName, "-", "_"),
  2292. `"current" is not an allowed value for this attribute`)
  2293. return ""
  2294. }
  2295. // "safeValue" is safe because it translates finalized codenames to a string
  2296. // with their SDK int.
  2297. safeValue := apiLevel.String()
  2298. return formattedOptionalAttribute(attrName, &safeValue)
  2299. }
  2300. // formats an attribute for the xml permissions file if the value is not null
  2301. // returns empty string otherwise
  2302. func formattedOptionalAttribute(attrName string, value *string) string {
  2303. if value == nil {
  2304. return ""
  2305. }
  2306. return fmt.Sprintf(` %s=\"%s\"\n`, attrName, *value)
  2307. }
  2308. func (module *sdkLibraryXml) permissionsContents(ctx android.ModuleContext) string {
  2309. libName := proptools.String(module.properties.Lib_name)
  2310. libNameAttr := formattedOptionalAttribute("name", &libName)
  2311. filePath := module.implPath(ctx)
  2312. filePathAttr := formattedOptionalAttribute("file", &filePath)
  2313. implicitFromAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-since", module.properties.On_bootclasspath_since)
  2314. implicitUntilAttr := formattedOptionalSdkLevelAttribute(ctx, "on-bootclasspath-before", module.properties.On_bootclasspath_before)
  2315. minSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "min-device-sdk", module.properties.Min_device_sdk)
  2316. maxSdkAttr := formattedOptionalSdkLevelAttribute(ctx, "max-device-sdk", module.properties.Max_device_sdk)
  2317. // <library> is understood in all android versions whereas <apex-library> is only understood from API T (and ignored before that).
  2318. // similarly, min_device_sdk is only understood from T. So if a library is using that, we need to use the apex-library to make sure this library is not loaded before T
  2319. var libraryTag string
  2320. if module.properties.Min_device_sdk != nil {
  2321. libraryTag = ` <apex-library\n`
  2322. } else {
  2323. libraryTag = ` <library\n`
  2324. }
  2325. return strings.Join([]string{
  2326. `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n`,
  2327. `<!-- Copyright (C) 2018 The Android Open Source Project\n`,
  2328. `\n`,
  2329. ` Licensed under the Apache License, Version 2.0 (the \"License\");\n`,
  2330. ` you may not use this file except in compliance with the License.\n`,
  2331. ` You may obtain a copy of the License at\n`,
  2332. `\n`,
  2333. ` http://www.apache.org/licenses/LICENSE-2.0\n`,
  2334. `\n`,
  2335. ` Unless required by applicable law or agreed to in writing, software\n`,
  2336. ` distributed under the License is distributed on an \"AS IS\" BASIS,\n`,
  2337. ` WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n`,
  2338. ` See the License for the specific language governing permissions and\n`,
  2339. ` limitations under the License.\n`,
  2340. `-->\n`,
  2341. `<permissions>\n`,
  2342. libraryTag,
  2343. libNameAttr,
  2344. filePathAttr,
  2345. implicitFromAttr,
  2346. implicitUntilAttr,
  2347. minSdkAttr,
  2348. maxSdkAttr,
  2349. ` />\n`,
  2350. `</permissions>\n`}, "")
  2351. }
  2352. func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) {
  2353. module.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform()
  2354. libName := proptools.String(module.properties.Lib_name)
  2355. module.selfValidate(ctx)
  2356. xmlContent := module.permissionsContents(ctx)
  2357. module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath
  2358. rule := android.NewRuleBuilder(pctx, ctx)
  2359. rule.Command().
  2360. Text("/bin/bash -c \"echo -e '" + xmlContent + "'\" > ").
  2361. Output(module.outputFilePath)
  2362. rule.Build("java_sdk_xml", "Permission XML")
  2363. module.installDirPath = android.PathForModuleInstall(ctx, "etc", module.SubDir())
  2364. }
  2365. func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries {
  2366. if module.hideApexVariantFromMake {
  2367. return []android.AndroidMkEntries{{
  2368. Disabled: true,
  2369. }}
  2370. }
  2371. return []android.AndroidMkEntries{{
  2372. Class: "ETC",
  2373. OutputFile: android.OptionalPathForPath(module.outputFilePath),
  2374. ExtraEntries: []android.AndroidMkExtraEntriesFunc{
  2375. func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
  2376. entries.SetString("LOCAL_MODULE_TAGS", "optional")
  2377. entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.String())
  2378. entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base())
  2379. },
  2380. },
  2381. }}
  2382. }
  2383. func (module *sdkLibraryXml) selfValidate(ctx android.ModuleContext) {
  2384. module.validateAtLeastTAttributes(ctx)
  2385. module.validateMinAndMaxDeviceSdk(ctx)
  2386. module.validateMinMaxDeviceSdkAndModuleMinSdk(ctx)
  2387. module.validateOnBootclasspathBeforeRequirements(ctx)
  2388. }
  2389. func (module *sdkLibraryXml) validateAtLeastTAttributes(ctx android.ModuleContext) {
  2390. t := android.ApiLevelOrPanic(ctx, "Tiramisu")
  2391. module.attrAtLeastT(ctx, t, module.properties.Min_device_sdk, "min_device_sdk")
  2392. module.attrAtLeastT(ctx, t, module.properties.Max_device_sdk, "max_device_sdk")
  2393. module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_before, "on_bootclasspath_before")
  2394. module.attrAtLeastT(ctx, t, module.properties.On_bootclasspath_since, "on_bootclasspath_since")
  2395. }
  2396. func (module *sdkLibraryXml) attrAtLeastT(ctx android.ModuleContext, t android.ApiLevel, attr *string, attrName string) {
  2397. if attr != nil {
  2398. if level, err := android.ApiLevelFromUser(ctx, *attr); err == nil {
  2399. // we will inform the user of invalid inputs when we try to write the
  2400. // permissions xml file so we don't need to do it here
  2401. if t.GreaterThan(level) {
  2402. ctx.PropertyErrorf(attrName, "Attribute value needs to be at least T")
  2403. }
  2404. }
  2405. }
  2406. }
  2407. func (module *sdkLibraryXml) validateMinAndMaxDeviceSdk(ctx android.ModuleContext) {
  2408. if module.properties.Min_device_sdk != nil && module.properties.Max_device_sdk != nil {
  2409. min, minErr := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
  2410. max, maxErr := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
  2411. if minErr == nil && maxErr == nil {
  2412. // we will inform the user of invalid inputs when we try to write the
  2413. // permissions xml file so we don't need to do it here
  2414. if min.GreaterThan(max) {
  2415. ctx.ModuleErrorf("min_device_sdk can't be greater than max_device_sdk")
  2416. }
  2417. }
  2418. }
  2419. }
  2420. func (module *sdkLibraryXml) validateMinMaxDeviceSdkAndModuleMinSdk(ctx android.ModuleContext) {
  2421. moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
  2422. if module.properties.Min_device_sdk != nil {
  2423. api, err := android.ApiLevelFromUser(ctx, *module.properties.Min_device_sdk)
  2424. if err == nil {
  2425. if moduleMinApi.GreaterThan(api) {
  2426. ctx.PropertyErrorf("min_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
  2427. }
  2428. }
  2429. }
  2430. if module.properties.Max_device_sdk != nil {
  2431. api, err := android.ApiLevelFromUser(ctx, *module.properties.Max_device_sdk)
  2432. if err == nil {
  2433. if moduleMinApi.GreaterThan(api) {
  2434. ctx.PropertyErrorf("max_device_sdk", "Can't be less than module's min sdk (%s)", moduleMinApi)
  2435. }
  2436. }
  2437. }
  2438. }
  2439. func (module *sdkLibraryXml) validateOnBootclasspathBeforeRequirements(ctx android.ModuleContext) {
  2440. moduleMinApi := android.ApiLevelOrPanic(ctx, *module.properties.Sdk_library_min_api_level)
  2441. if module.properties.On_bootclasspath_before != nil {
  2442. t := android.ApiLevelOrPanic(ctx, "Tiramisu")
  2443. // if we use the attribute, then we need to do this validation
  2444. if moduleMinApi.LessThan(t) {
  2445. // if minAPi is < T, then we need to have min_device_sdk (which only accepts T+)
  2446. if module.properties.Min_device_sdk == nil {
  2447. ctx.PropertyErrorf("on_bootclasspath_before", "Using this property requires that the module's min_sdk_version or the shared library's min_device_sdk is at least T")
  2448. }
  2449. }
  2450. }
  2451. }
  2452. type sdkLibrarySdkMemberType struct {
  2453. android.SdkMemberTypeBase
  2454. }
  2455. func (s *sdkLibrarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
  2456. ctx.AddVariationDependencies(nil, dependencyTag, names...)
  2457. }
  2458. func (s *sdkLibrarySdkMemberType) IsInstance(module android.Module) bool {
  2459. _, ok := module.(*SdkLibrary)
  2460. return ok
  2461. }
  2462. func (s *sdkLibrarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
  2463. return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_sdk_library_import")
  2464. }
  2465. func (s *sdkLibrarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
  2466. return &sdkLibrarySdkMemberProperties{}
  2467. }
  2468. var javaSdkLibrarySdkMemberType = &sdkLibrarySdkMemberType{
  2469. android.SdkMemberTypeBase{
  2470. PropertyName: "java_sdk_libs",
  2471. SupportsSdk: true,
  2472. },
  2473. }
  2474. type sdkLibrarySdkMemberProperties struct {
  2475. android.SdkMemberPropertiesBase
  2476. // Stem name for files in the sdk snapshot.
  2477. //
  2478. // This is used to construct the path names of various sdk library files in the sdk snapshot to
  2479. // make sure that they match the finalized versions of those files in prebuilts/sdk.
  2480. //
  2481. // This property is marked as keep so that it will be kept in all instances of this struct, will
  2482. // not be cleared but will be copied to common structs. That is needed because this field is used
  2483. // to construct many file names for other parts of this struct and so it needs to be present in
  2484. // all structs. If it was not marked as keep then it would be cleared in some structs and so would
  2485. // be unavailable for generating file names if there were other properties that were still set.
  2486. Stem string `sdk:"keep"`
  2487. // Scope to per scope properties.
  2488. Scopes map[*apiScope]*scopeProperties
  2489. // The Java stubs source files.
  2490. Stub_srcs []string
  2491. // The naming scheme.
  2492. Naming_scheme *string
  2493. // True if the java_sdk_library_import is for a shared library, false
  2494. // otherwise.
  2495. Shared_library *bool
  2496. // True if the stub imports should produce dex jars.
  2497. Compile_dex *bool
  2498. // The paths to the doctag files to add to the prebuilt.
  2499. Doctag_paths android.Paths
  2500. Permitted_packages []string
  2501. // Signals that this shared library is part of the bootclasspath starting
  2502. // on the version indicated in this attribute.
  2503. //
  2504. // This will make platforms at this level and above to ignore
  2505. // <uses-library> tags with this library name because the library is already
  2506. // available
  2507. On_bootclasspath_since *string
  2508. // Signals that this shared library was part of the bootclasspath before
  2509. // (but not including) the version indicated in this attribute.
  2510. //
  2511. // The system will automatically add a <uses-library> tag with this library to
  2512. // apps that target any SDK less than the version indicated in this attribute.
  2513. On_bootclasspath_before *string
  2514. // Indicates that PackageManager should ignore this shared library if the
  2515. // platform is below the version indicated in this attribute.
  2516. //
  2517. // This means that the device won't recognise this library as installed.
  2518. Min_device_sdk *string
  2519. // Indicates that PackageManager should ignore this shared library if the
  2520. // platform is above the version indicated in this attribute.
  2521. //
  2522. // This means that the device won't recognise this library as installed.
  2523. Max_device_sdk *string
  2524. }
  2525. type scopeProperties struct {
  2526. Jars android.Paths
  2527. StubsSrcJar android.Path
  2528. CurrentApiFile android.Path
  2529. RemovedApiFile android.Path
  2530. AnnotationsZip android.Path `supported_build_releases:"Tiramisu+"`
  2531. SdkVersion string
  2532. }
  2533. func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
  2534. sdk := variant.(*SdkLibrary)
  2535. // Copy the stem name for files in the sdk snapshot.
  2536. s.Stem = sdk.distStem()
  2537. s.Scopes = make(map[*apiScope]*scopeProperties)
  2538. for _, apiScope := range allApiScopes {
  2539. paths := sdk.findScopePaths(apiScope)
  2540. if paths == nil {
  2541. continue
  2542. }
  2543. jars := paths.stubsImplPath
  2544. if len(jars) > 0 {
  2545. properties := scopeProperties{}
  2546. properties.Jars = jars
  2547. properties.SdkVersion = sdk.sdkVersionForStubsLibrary(ctx.SdkModuleContext(), apiScope)
  2548. properties.StubsSrcJar = paths.stubsSrcJar.Path()
  2549. if paths.currentApiFilePath.Valid() {
  2550. properties.CurrentApiFile = paths.currentApiFilePath.Path()
  2551. }
  2552. if paths.removedApiFilePath.Valid() {
  2553. properties.RemovedApiFile = paths.removedApiFilePath.Path()
  2554. }
  2555. // The annotations zip is only available for modules that set annotations_enabled: true.
  2556. if paths.annotationsZip.Valid() {
  2557. properties.AnnotationsZip = paths.annotationsZip.Path()
  2558. }
  2559. s.Scopes[apiScope] = &properties
  2560. }
  2561. }
  2562. s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme
  2563. s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary())
  2564. s.Compile_dex = sdk.dexProperties.Compile_dex
  2565. s.Doctag_paths = sdk.doctagPaths
  2566. s.Permitted_packages = sdk.PermittedPackagesForUpdatableBootJars()
  2567. s.On_bootclasspath_since = sdk.commonSdkLibraryProperties.On_bootclasspath_since
  2568. s.On_bootclasspath_before = sdk.commonSdkLibraryProperties.On_bootclasspath_before
  2569. s.Min_device_sdk = sdk.commonSdkLibraryProperties.Min_device_sdk
  2570. s.Max_device_sdk = sdk.commonSdkLibraryProperties.Max_device_sdk
  2571. }
  2572. func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
  2573. if s.Naming_scheme != nil {
  2574. propertySet.AddProperty("naming_scheme", proptools.String(s.Naming_scheme))
  2575. }
  2576. if s.Shared_library != nil {
  2577. propertySet.AddProperty("shared_library", *s.Shared_library)
  2578. }
  2579. if s.Compile_dex != nil {
  2580. propertySet.AddProperty("compile_dex", *s.Compile_dex)
  2581. }
  2582. if len(s.Permitted_packages) > 0 {
  2583. propertySet.AddProperty("permitted_packages", s.Permitted_packages)
  2584. }
  2585. stem := s.Stem
  2586. for _, apiScope := range allApiScopes {
  2587. if properties, ok := s.Scopes[apiScope]; ok {
  2588. scopeSet := propertySet.AddPropertySet(apiScope.propertyName)
  2589. scopeDir := apiScope.snapshotRelativeDir()
  2590. var jars []string
  2591. for _, p := range properties.Jars {
  2592. dest := filepath.Join(scopeDir, stem+"-stubs.jar")
  2593. ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
  2594. jars = append(jars, dest)
  2595. }
  2596. scopeSet.AddProperty("jars", jars)
  2597. if ctx.SdkModuleContext().Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_USE_SRCJAR") {
  2598. // Copy the stubs source jar into the snapshot zip as is.
  2599. srcJarSnapshotPath := filepath.Join(scopeDir, stem+".srcjar")
  2600. ctx.SnapshotBuilder().CopyToSnapshot(properties.StubsSrcJar, srcJarSnapshotPath)
  2601. scopeSet.AddProperty("stub_srcs", []string{srcJarSnapshotPath})
  2602. } else {
  2603. // Merge the stubs source jar into the snapshot zip so that when it is unpacked
  2604. // the source files are also unpacked.
  2605. snapshotRelativeDir := filepath.Join(scopeDir, stem+"_stub_sources")
  2606. ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir)
  2607. scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir})
  2608. }
  2609. if properties.CurrentApiFile != nil {
  2610. currentApiSnapshotPath := apiScope.snapshotRelativeCurrentApiTxtPath(stem)
  2611. ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, currentApiSnapshotPath)
  2612. scopeSet.AddProperty("current_api", currentApiSnapshotPath)
  2613. }
  2614. if properties.RemovedApiFile != nil {
  2615. removedApiSnapshotPath := apiScope.snapshotRelativeRemovedApiTxtPath(stem)
  2616. ctx.SnapshotBuilder().CopyToSnapshot(properties.RemovedApiFile, removedApiSnapshotPath)
  2617. scopeSet.AddProperty("removed_api", removedApiSnapshotPath)
  2618. }
  2619. if properties.AnnotationsZip != nil {
  2620. annotationsSnapshotPath := filepath.Join(scopeDir, stem+"_annotations.zip")
  2621. ctx.SnapshotBuilder().CopyToSnapshot(properties.AnnotationsZip, annotationsSnapshotPath)
  2622. scopeSet.AddProperty("annotations", annotationsSnapshotPath)
  2623. }
  2624. if properties.SdkVersion != "" {
  2625. scopeSet.AddProperty("sdk_version", properties.SdkVersion)
  2626. }
  2627. }
  2628. }
  2629. if len(s.Doctag_paths) > 0 {
  2630. dests := []string{}
  2631. for _, p := range s.Doctag_paths {
  2632. dest := filepath.Join("doctags", p.Rel())
  2633. ctx.SnapshotBuilder().CopyToSnapshot(p, dest)
  2634. dests = append(dests, dest)
  2635. }
  2636. propertySet.AddProperty("doctag_files", dests)
  2637. }
  2638. }