12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744 |
- // Copyright 2018 Google Inc. All rights reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package apex
- import (
- "fmt"
- "os"
- "path"
- "path/filepath"
- "reflect"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "testing"
- "github.com/google/blueprint/proptools"
- "android/soong/android"
- "android/soong/bpf"
- "android/soong/cc"
- "android/soong/dexpreopt"
- prebuilt_etc "android/soong/etc"
- "android/soong/java"
- "android/soong/rust"
- "android/soong/sh"
- )
- // names returns name list from white space separated string
- func names(s string) (ns []string) {
- for _, n := range strings.Split(s, " ") {
- if len(n) > 0 {
- ns = append(ns, n)
- }
- }
- return
- }
- func testApexError(t *testing.T, pattern, bp string, preparers ...android.FixturePreparer) {
- t.Helper()
- android.GroupFixturePreparers(
- prepareForApexTest,
- android.GroupFixturePreparers(preparers...),
- ).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
- RunTestWithBp(t, bp)
- }
- func testApex(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext {
- t.Helper()
- optionalBpPreparer := android.NullFixturePreparer
- if bp != "" {
- optionalBpPreparer = android.FixtureWithRootAndroidBp(bp)
- }
- result := android.GroupFixturePreparers(
- prepareForApexTest,
- android.GroupFixturePreparers(preparers...),
- optionalBpPreparer,
- ).RunTest(t)
- return result.TestContext
- }
- func withFiles(files android.MockFS) android.FixturePreparer {
- return files.AddToFixture()
- }
- func withTargets(targets map[android.OsType][]android.Target) android.FixturePreparer {
- return android.FixtureModifyConfig(func(config android.Config) {
- for k, v := range targets {
- config.Targets[k] = v
- }
- })
- }
- // withNativeBridgeTargets sets configuration with targets including:
- // - X86_64 (primary)
- // - X86 (secondary)
- // - Arm64 on X86_64 (native bridge)
- // - Arm on X86 (native bridge)
- var withNativeBridgeEnabled = android.FixtureModifyConfig(
- func(config android.Config) {
- config.Targets[android.Android] = []android.Target{
- {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}},
- NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
- {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}},
- NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
- {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}},
- NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86_64", NativeBridgeRelativePath: "arm64"},
- {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
- NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86", NativeBridgeRelativePath: "arm"},
- }
- },
- )
- func withManifestPackageNameOverrides(specs []string) android.FixturePreparer {
- return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.ManifestPackageNameOverrides = specs
- })
- }
- var withBinder32bit = android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.Binder32bit = proptools.BoolPtr(true)
- },
- )
- var withUnbundledBuild = android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.Unbundled_build = proptools.BoolPtr(true)
- },
- )
- // Legacy preparer used for running tests within the apex package.
- //
- // This includes everything that was needed to run any test in the apex package prior to the
- // introduction of the test fixtures. Tests that are being converted to use fixtures directly
- // rather than through the testApex...() methods should avoid using this and instead use the
- // various preparers directly, using android.GroupFixturePreparers(...) to group them when
- // necessary.
- //
- // deprecated
- var prepareForApexTest = android.GroupFixturePreparers(
- // General preparers in alphabetical order as test infrastructure will enforce correct
- // registration order.
- android.PrepareForTestWithAndroidBuildComponents,
- bpf.PrepareForTestWithBpf,
- cc.PrepareForTestWithCcBuildComponents,
- java.PrepareForTestWithJavaDefaultModules,
- prebuilt_etc.PrepareForTestWithPrebuiltEtc,
- rust.PrepareForTestWithRustDefaultModules,
- sh.PrepareForTestWithShBuildComponents,
- PrepareForTestWithApexBuildComponents,
- // Additional apex test specific preparers.
- android.FixtureAddTextFile("system/sepolicy/Android.bp", `
- filegroup {
- name: "myapex-file_contexts",
- srcs: [
- "apex/myapex-file_contexts",
- ],
- }
- `),
- prepareForTestWithMyapex,
- android.FixtureMergeMockFs(android.MockFS{
- "a.java": nil,
- "PrebuiltAppFoo.apk": nil,
- "PrebuiltAppFooPriv.apk": nil,
- "apex_manifest.json": nil,
- "AndroidManifest.xml": nil,
- "system/sepolicy/apex/myapex.updatable-file_contexts": nil,
- "system/sepolicy/apex/myapex2-file_contexts": nil,
- "system/sepolicy/apex/otherapex-file_contexts": nil,
- "system/sepolicy/apex/com.android.vndk-file_contexts": nil,
- "system/sepolicy/apex/com.android.vndk.current-file_contexts": nil,
- "mylib.cpp": nil,
- "mytest.cpp": nil,
- "mytest1.cpp": nil,
- "mytest2.cpp": nil,
- "mytest3.cpp": nil,
- "myprebuilt": nil,
- "my_include": nil,
- "foo/bar/MyClass.java": nil,
- "prebuilt.jar": nil,
- "prebuilt.so": nil,
- "vendor/foo/devkeys/test.x509.pem": nil,
- "vendor/foo/devkeys/test.pk8": nil,
- "testkey.x509.pem": nil,
- "testkey.pk8": nil,
- "testkey.override.x509.pem": nil,
- "testkey.override.pk8": nil,
- "vendor/foo/devkeys/testkey.avbpubkey": nil,
- "vendor/foo/devkeys/testkey.pem": nil,
- "NOTICE": nil,
- "custom_notice": nil,
- "custom_notice_for_static_lib": nil,
- "testkey2.avbpubkey": nil,
- "testkey2.pem": nil,
- "myapex-arm64.apex": nil,
- "myapex-arm.apex": nil,
- "myapex.apks": nil,
- "frameworks/base/api/current.txt": nil,
- "framework/aidl/a.aidl": nil,
- "build/make/core/proguard.flags": nil,
- "build/make/core/proguard_basic_keeps.flags": nil,
- "dummy.txt": nil,
- "baz": nil,
- "bar/baz": nil,
- "testdata/baz": nil,
- "AppSet.apks": nil,
- "foo.rs": nil,
- "libfoo.jar": nil,
- "libbar.jar": nil,
- },
- ),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = proptools.StringPtr("current")
- variables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
- variables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
- variables.Platform_sdk_codename = proptools.StringPtr("Q")
- variables.Platform_sdk_final = proptools.BoolPtr(false)
- // "Tiramisu" needs to be in the next line for compatibility with soong code,
- // not because of these tests specifically (it's not used by the tests)
- variables.Platform_version_active_codenames = []string{"Q", "Tiramisu"}
- variables.Platform_vndk_version = proptools.StringPtr("29")
- }),
- )
- var prepareForTestWithMyapex = android.FixtureMergeMockFs(android.MockFS{
- "system/sepolicy/apex/myapex-file_contexts": nil,
- })
- // ensure that 'result' equals 'expected'
- func ensureEquals(t *testing.T, result string, expected string) {
- t.Helper()
- if result != expected {
- t.Errorf("%q != %q", expected, result)
- }
- }
- // ensure that 'result' contains 'expected'
- func ensureContains(t *testing.T, result string, expected string) {
- t.Helper()
- if !strings.Contains(result, expected) {
- t.Errorf("%q is not found in %q", expected, result)
- }
- }
- // ensure that 'result' contains 'expected' exactly one time
- func ensureContainsOnce(t *testing.T, result string, expected string) {
- t.Helper()
- count := strings.Count(result, expected)
- if count != 1 {
- t.Errorf("%q is found %d times (expected 1 time) in %q", expected, count, result)
- }
- }
- // ensures that 'result' does not contain 'notExpected'
- func ensureNotContains(t *testing.T, result string, notExpected string) {
- t.Helper()
- if strings.Contains(result, notExpected) {
- t.Errorf("%q is found in %q", notExpected, result)
- }
- }
- func ensureMatches(t *testing.T, result string, expectedRex string) {
- ok, err := regexp.MatchString(expectedRex, result)
- if err != nil {
- t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err)
- return
- }
- if !ok {
- t.Errorf("%s does not match regular expession %s", result, expectedRex)
- }
- }
- func ensureListContains(t *testing.T, result []string, expected string) {
- t.Helper()
- if !android.InList(expected, result) {
- t.Errorf("%q is not found in %v", expected, result)
- }
- }
- func ensureListNotContains(t *testing.T, result []string, notExpected string) {
- t.Helper()
- if android.InList(notExpected, result) {
- t.Errorf("%q is found in %v", notExpected, result)
- }
- }
- func ensureListEmpty(t *testing.T, result []string) {
- t.Helper()
- if len(result) > 0 {
- t.Errorf("%q is expected to be empty", result)
- }
- }
- func ensureListNotEmpty(t *testing.T, result []string) {
- t.Helper()
- if len(result) == 0 {
- t.Errorf("%q is expected to be not empty", result)
- }
- }
- // Minimal test
- func TestBasicApex(t *testing.T) {
- ctx := testApex(t, `
- apex_defaults {
- name: "myapex-defaults",
- manifest: ":myapex.manifest",
- androidManifest: ":myapex.androidmanifest",
- key: "myapex.key",
- binaries: ["foo.rust"],
- native_shared_libs: [
- "mylib",
- "libfoo.ffi",
- ],
- rust_dyn_libs: ["libfoo.dylib.rust"],
- multilib: {
- both: {
- binaries: ["foo"],
- }
- },
- java_libs: [
- "myjar",
- "myjar_dex",
- ],
- updatable: false,
- }
- apex {
- name: "myapex",
- defaults: ["myapex-defaults"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- filegroup {
- name: "myapex.manifest",
- srcs: ["apex_manifest.json"],
- }
- filegroup {
- name: "myapex.androidmanifest",
- srcs: ["AndroidManifest.xml"],
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: [
- "mylib2",
- "libbar.ffi",
- ],
- system_shared_libs: [],
- stl: "none",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- cc_binary {
- name: "foo",
- srcs: ["mylib.cpp"],
- compile_multilib: "both",
- multilib: {
- lib32: {
- suffix: "32",
- },
- lib64: {
- suffix: "64",
- },
- },
- symlinks: ["foo_link_"],
- symlink_preferred_arch: true,
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex", "com.android.gki.*" ],
- }
- rust_binary {
- name: "foo.rust",
- srcs: ["foo.rs"],
- rlibs: ["libfoo.rlib.rust"],
- dylibs: ["libfoo.dylib.rust"],
- apex_available: ["myapex"],
- }
- rust_library_rlib {
- name: "libfoo.rlib.rust",
- srcs: ["foo.rs"],
- crate_name: "foo",
- apex_available: ["myapex"],
- shared_libs: ["libfoo.shared_from_rust"],
- }
- cc_library_shared {
- name: "libfoo.shared_from_rust",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: ["myapex"],
- }
- rust_library_dylib {
- name: "libfoo.dylib.rust",
- srcs: ["foo.rs"],
- crate_name: "foo",
- apex_available: ["myapex"],
- }
- rust_ffi_shared {
- name: "libfoo.ffi",
- srcs: ["foo.rs"],
- crate_name: "foo",
- apex_available: ["myapex"],
- }
- rust_ffi_shared {
- name: "libbar.ffi",
- srcs: ["foo.rs"],
- crate_name: "bar",
- apex_available: ["myapex"],
- }
- apex {
- name: "com.android.gki.fake",
- binaries: ["foo"],
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- cc_library_shared {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- notice: "custom_notice",
- static_libs: ["libstatic"],
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- cc_prebuilt_library_shared {
- name: "mylib2",
- srcs: ["prebuilt.so"],
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- cc_library_static {
- name: "libstatic",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- notice: "custom_notice_for_static_lib",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- stem: "myjar_stem",
- sdk_version: "none",
- system_modules: "none",
- static_libs: ["myotherjar"],
- libs: ["mysharedjar"],
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- dex_import {
- name: "myjar_dex",
- jars: ["prebuilt.jar"],
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- java_library {
- name: "myotherjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- java_library {
- name: "mysharedjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- // Make sure that Android.mk is created
- ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, ab)
- var builder strings.Builder
- data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
- optFlags := apexRule.Args["opt_flags"]
- ensureContains(t, optFlags, "--pubkey vendor/foo/devkeys/testkey.avbpubkey")
- // Ensure that the NOTICE output is being packaged as an asset.
- ensureContains(t, optFlags, "--assets_dir out/soong/.intermediates/myapex/android_common_myapex_image/NOTICE")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that main rule creates an output
- ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
- // Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("foo.rust"), "android_arm64_armv8-a_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.ffi"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that apex variant is created for the indirect dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.rlib.rust"), "android_arm64_armv8-a_rlib_dylib-std_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("libbar.ffi"), "android_arm64_armv8-a_shared_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.shared_from_rust"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that both direct and indirect deps are copied into apex
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
- ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
- ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar")
- ensureContains(t, copyCmds, "image.apex/lib64/libfoo.dylib.rust.dylib.so")
- ensureContains(t, copyCmds, "image.apex/lib64/libfoo.ffi.so")
- ensureContains(t, copyCmds, "image.apex/lib64/libbar.ffi.so")
- ensureContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
- // .. but not for java libs
- ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
- ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
- // Ensure that the platform variant ends with _shared or _common
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared")
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared")
- ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common")
- ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common")
- ensureListContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common")
- // Ensure that dynamic dependency to java libs are not included
- ensureListNotContains(t, ctx.ModuleVariantsForTests("mysharedjar"), "android_common_myapex")
- // Ensure that all symlinks are present.
- found_foo_link_64 := false
- found_foo := false
- for _, cmd := range strings.Split(copyCmds, " && ") {
- if strings.HasPrefix(cmd, "ln -sfn foo64") {
- if strings.HasSuffix(cmd, "bin/foo") {
- found_foo = true
- } else if strings.HasSuffix(cmd, "bin/foo_link_64") {
- found_foo_link_64 = true
- }
- }
- }
- good := found_foo && found_foo_link_64
- if !good {
- t.Errorf("Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s", found_foo, found_foo_link_64, copyCmds)
- }
- mergeNoticesRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("mergeNoticesRule")
- noticeInputs := mergeNoticesRule.Inputs.Strings()
- if len(noticeInputs) != 3 {
- t.Errorf("number of input notice files: expected = 3, actual = %q", len(noticeInputs))
- }
- ensureListContains(t, noticeInputs, "NOTICE")
- ensureListContains(t, noticeInputs, "custom_notice")
- ensureListContains(t, noticeInputs, "custom_notice_for_static_lib")
- fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
- ensureListContains(t, fullDepsInfo, " myjar(minSdkVersion:(no version)) <- myapex")
- ensureListContains(t, fullDepsInfo, " mylib2(minSdkVersion:(no version)) <- mylib")
- ensureListContains(t, fullDepsInfo, " myotherjar(minSdkVersion:(no version)) <- myjar")
- ensureListContains(t, fullDepsInfo, " mysharedjar(minSdkVersion:(no version)) (external) <- myjar")
- flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
- ensureListContains(t, flatDepsInfo, "myjar(minSdkVersion:(no version))")
- ensureListContains(t, flatDepsInfo, "mylib2(minSdkVersion:(no version))")
- ensureListContains(t, flatDepsInfo, "myotherjar(minSdkVersion:(no version))")
- ensureListContains(t, flatDepsInfo, "mysharedjar(minSdkVersion:(no version)) (external)")
- }
- func TestDefaults(t *testing.T) {
- ctx := testApex(t, `
- apex_defaults {
- name: "myapex-defaults",
- key: "myapex.key",
- prebuilts: ["myetc"],
- native_shared_libs: ["mylib"],
- java_libs: ["myjar"],
- apps: ["AppFoo"],
- rros: ["rro"],
- bpfs: ["bpf"],
- updatable: false,
- }
- prebuilt_etc {
- name: "myetc",
- src: "myprebuilt",
- }
- apex {
- name: "myapex",
- defaults: ["myapex-defaults"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- apex_available: [ "myapex" ],
- }
- android_app {
- name: "AppFoo",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- apex_available: [ "myapex" ],
- }
- runtime_resource_overlay {
- name: "rro",
- theme: "blue",
- }
- bpf {
- name: "bpf",
- srcs: ["bpf.c", "bpf2.c"],
- }
- `)
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "etc/myetc",
- "javalib/myjar.jar",
- "lib64/mylib.so",
- "app/AppFoo/AppFoo.apk",
- "overlay/blue/rro.apk",
- "etc/bpf/bpf.o",
- "etc/bpf/bpf2.o",
- })
- }
- func TestApexManifest(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- args := module.Rule("apexRule").Args
- if manifest := args["manifest"]; manifest != module.Output("apex_manifest.pb").Output.String() {
- t.Error("manifest should be apex_manifest.pb, but " + manifest)
- }
- }
- func TestApexManifestMinSdkVersion(t *testing.T) {
- ctx := testApex(t, `
- apex_defaults {
- name: "my_defaults",
- key: "myapex.key",
- product_specific: true,
- file_contexts: ":my-file-contexts",
- updatable: false,
- }
- apex {
- name: "myapex_30",
- min_sdk_version: "30",
- defaults: ["my_defaults"],
- }
- apex {
- name: "myapex_current",
- min_sdk_version: "current",
- defaults: ["my_defaults"],
- }
- apex {
- name: "myapex_none",
- defaults: ["my_defaults"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- filegroup {
- name: "my-file-contexts",
- srcs: ["product_specific_file_contexts"],
- }
- `, withFiles(map[string][]byte{
- "product_specific_file_contexts": nil,
- }), android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Always_use_prebuilt_sdks = proptools.BoolPtr(false)
- }), android.FixtureMergeEnv(map[string]string{
- "UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT": "true",
- }))
- testCases := []struct {
- module string
- minSdkVersion string
- }{
- {
- module: "myapex_30",
- minSdkVersion: "30",
- },
- {
- module: "myapex_current",
- minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)",
- },
- {
- module: "myapex_none",
- minSdkVersion: "Q.$$(cat out/soong/api_fingerprint.txt)",
- },
- }
- for _, tc := range testCases {
- module := ctx.ModuleForTests(tc.module, "android_common_"+tc.module+"_image")
- args := module.Rule("apexRule").Args
- optFlags := args["opt_flags"]
- if !strings.Contains(optFlags, "--min_sdk_version "+tc.minSdkVersion) {
- t.Errorf("%s: Expected min_sdk_version=%s, got: %s", tc.module, tc.minSdkVersion, optFlags)
- }
- }
- }
- func TestBasicZipApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- payload_type: "zip",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- `)
- zipApexRule := ctx.ModuleForTests("myapex", "android_common_myapex_zip").Rule("zipApexRule")
- copyCmds := zipApexRule.Args["copy_commands"]
- // Ensure that main rule creates an output
- ensureContains(t, zipApexRule.Output.String(), "myapex.zipapex.unsigned")
- // Ensure that APEX variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that APEX variant is created for the indirect dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that both direct and indirect deps are copied into apex
- ensureContains(t, copyCmds, "image.zipapex/lib64/mylib.so")
- ensureContains(t, copyCmds, "image.zipapex/lib64/mylib2.so")
- }
- func TestApexWithStubs(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "mylib3"],
- binaries: ["foo.rust"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2", "mylib3"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- cflags: ["-include mylib.h"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1", "2", "3"],
- },
- }
- cc_library {
- name: "mylib3",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib4"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["10", "11", "12"],
- },
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "mylib4",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- rust_binary {
- name: "foo.rust",
- srcs: ["foo.rs"],
- shared_libs: ["libfoo.shared_from_rust"],
- prefer_rlib: true,
- apex_available: ["myapex"],
- }
- cc_library_shared {
- name: "libfoo.shared_from_rust",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["10", "11", "12"],
- },
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that direct non-stubs dep is always included
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- // Ensure that indirect stubs dep is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
- // Ensure that direct stubs dep is included
- ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
- // Ensure that mylib is linking with the latest version of stubs for mylib2
- ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
- // ... and not linking to the non-stub (impl) variant of mylib2
- ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
- ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex10000/mylib3.so")
- // .. and not linking to the stubs variant of mylib3
- ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_12/mylib3.so")
- // Comment out this test. Now it fails after the optimization of sharing "cflags" in cc/cc.go
- // is replaced by sharing of "cFlags" in cc/builder.go.
- // The "cflags" contains "-include mylib.h", but cFlags contained only a reference to the
- // module variable representing "cflags". So it was not detected by ensureNotContains.
- // Now "cFlags" is a reference to a module variable like $flags1, which includes all previous
- // content of "cflags". ModuleForTests...Args["cFlags"] returns the full string of $flags1,
- // including the original cflags's "-include mylib.h".
- //
- // Ensure that stubs libs are built without -include flags
- // mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- // ensureNotContains(t, mylib2Cflags, "-include ")
- // Ensure that genstub is invoked with --apex
- ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"])
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "lib64/mylib.so",
- "lib64/mylib3.so",
- "lib64/mylib4.so",
- "bin/foo.rust",
- "lib64/libc++.so", // by the implicit dependency from foo.rust
- "lib64/liblog.so", // by the implicit dependency from foo.rust
- })
- // Ensure that stub dependency from a rust module is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
- // The rust module is linked to the stub cc library
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
- ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
- ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
- }
- func TestApexCanUsePrivateApis(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- binaries: ["foo.rust"],
- updatable: false,
- platform_apis: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- cflags: ["-include mylib.h"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1", "2", "3"],
- },
- }
- rust_binary {
- name: "foo.rust",
- srcs: ["foo.rs"],
- shared_libs: ["libfoo.shared_from_rust"],
- prefer_rlib: true,
- apex_available: ["myapex"],
- }
- cc_library_shared {
- name: "libfoo.shared_from_rust",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["10", "11", "12"],
- },
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that indirect stubs dep is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
- ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
- // Ensure that we are using non-stub variants of mylib2 and libfoo.shared_from_rust (because
- // of the platform_apis: true)
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000_private").Rule("ld").Args["libFlags"]
- ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
- ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000_private").Rule("rustc").Args["linkFlags"]
- ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
- ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
- }
- func TestApexWithStubsWithMinSdkVersion(t *testing.T) {
- t.Parallel()
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "mylib3"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2", "mylib3"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- min_sdk_version: "28",
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- cflags: ["-include mylib.h"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["28", "29", "30", "current"],
- },
- min_sdk_version: "28",
- }
- cc_library {
- name: "mylib3",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib4"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["28", "29", "30", "current"],
- },
- apex_available: [ "myapex" ],
- min_sdk_version: "28",
- }
- cc_library {
- name: "mylib4",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- min_sdk_version: "28",
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that direct non-stubs dep is always included
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- // Ensure that indirect stubs dep is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
- // Ensure that direct stubs dep is included
- ensureContains(t, copyCmds, "image.apex/lib64/mylib3.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex29").Rule("ld").Args["libFlags"]
- // Ensure that mylib is linking with the latest version of stub for mylib2
- ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
- // ... and not linking to the non-stub (impl) variant of mylib2
- ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- // Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
- ensureContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_apex29/mylib3.so")
- // .. and not linking to the stubs variant of mylib3
- ensureNotContains(t, mylibLdFlags, "mylib3/android_arm64_armv8-a_shared_29/mylib3.so")
- // Ensure that stubs libs are built without -include flags
- mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
- ensureNotContains(t, mylib2Cflags, "-include ")
- // Ensure that genstub is invoked with --apex
- ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"])
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "lib64/mylib.so",
- "lib64/mylib3.so",
- "lib64/mylib4.so",
- })
- }
- func TestApex_PlatformUsesLatestStubFromApex(t *testing.T) {
- t.Parallel()
- // myapex (Z)
- // mylib -----------------.
- // |
- // otherapex (29) |
- // libstub's versions: 29 Z current
- // |
- // <platform> |
- // libplatform ----------------'
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- min_sdk_version: "Z", // non-final
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["libstub"],
- apex_available: ["myapex"],
- min_sdk_version: "Z",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- apex {
- name: "otherapex",
- key: "myapex.key",
- native_shared_libs: ["libstub"],
- min_sdk_version: "29",
- }
- cc_library {
- name: "libstub",
- srcs: ["mylib.cpp"],
- stubs: {
- versions: ["29", "Z", "current"],
- },
- apex_available: ["otherapex"],
- min_sdk_version: "29",
- }
- // platform module depending on libstub from otherapex should use the latest stub("current")
- cc_library {
- name: "libplatform",
- srcs: ["mylib.cpp"],
- shared_libs: ["libstub"],
- }
- `,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_sdk_codename = proptools.StringPtr("Z")
- variables.Platform_sdk_final = proptools.BoolPtr(false)
- variables.Platform_version_active_codenames = []string{"Z"}
- }),
- )
- // Ensure that mylib from myapex is built against the latest stub (current)
- mylibCflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCflags, "-D__LIBSTUB_API__=10000 ")
- mylibLdflags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
- ensureContains(t, mylibLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ")
- // Ensure that libplatform is built against latest stub ("current") of mylib3 from the apex
- libplatformCflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- ensureContains(t, libplatformCflags, "-D__LIBSTUB_API__=10000 ") // "current" maps to 10000
- libplatformLdflags := ctx.ModuleForTests("libplatform", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
- ensureContains(t, libplatformLdflags, "libstub/android_arm64_armv8-a_shared_current/libstub.so ")
- }
- func TestApexWithExplicitStubsDependency(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex2",
- key: "myapex2.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex2.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["libfoo#10"],
- static_libs: ["libbaz"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex2" ],
- }
- cc_library {
- name: "libfoo",
- srcs: ["mylib.cpp"],
- shared_libs: ["libbar"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["10", "20", "30"],
- },
- }
- cc_library {
- name: "libbar",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- }
- cc_library_static {
- name: "libbaz",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex2" ],
- }
- `)
- apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that direct non-stubs dep is always included
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- // Ensure that indirect stubs dep is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
- // Ensure that dependency of stubs is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
- // Ensure that mylib is linking with version 10 of libfoo
- ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
- // ... and not linking to the non-stub (impl) variant of libfoo
- ensureNotContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared/libfoo.so")
- libFooStubsLdFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_10").Rule("ld").Args["libFlags"]
- // Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
- ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
- fullDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/fulllist.txt").Args["content"], "\\n")
- ensureListContains(t, fullDepsInfo, " libfoo(minSdkVersion:(no version)) (external) <- mylib")
- flatDepsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("depsinfo/flatlist.txt").Args["content"], "\\n")
- ensureListContains(t, flatDepsInfo, "libfoo(minSdkVersion:(no version)) (external)")
- }
- func TestApexWithRuntimeLibsDependency(t *testing.T) {
- /*
- myapex
- |
- v (runtime_libs)
- mylib ------+------> libfoo [provides stub]
- |
- `------> libbar
- */
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- runtime_libs: ["libfoo", "libbar"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "libfoo",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["10", "20", "30"],
- },
- }
- cc_library {
- name: "libbar",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that direct non-stubs dep is always included
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- // Ensure that indirect stubs dep is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
- // Ensure that runtime_libs dep in included
- ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
- ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
- ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libfoo.so")
- }
- var prepareForTestOfRuntimeApexWithHwasan = android.GroupFixturePreparers(
- cc.PrepareForTestWithCcBuildComponents,
- PrepareForTestWithApexBuildComponents,
- android.FixtureAddTextFile("bionic/apex/Android.bp", `
- apex {
- name: "com.android.runtime",
- key: "com.android.runtime.key",
- native_shared_libs: ["libc"],
- updatable: false,
- }
- apex_key {
- name: "com.android.runtime.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `),
- android.FixtureAddFile("system/sepolicy/apex/com.android.runtime-file_contexts", nil),
- )
- func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt(t *testing.T) {
- result := android.GroupFixturePreparers(prepareForTestOfRuntimeApexWithHwasan).RunTestWithBp(t, `
- cc_library {
- name: "libc",
- no_libcrt: true,
- nocrt: true,
- stl: "none",
- system_shared_libs: [],
- stubs: { versions: ["1"] },
- apex_available: ["com.android.runtime"],
- sanitize: {
- hwaddress: true,
- }
- }
- cc_prebuilt_library_shared {
- name: "libclang_rt.hwasan-aarch64-android",
- no_libcrt: true,
- nocrt: true,
- stl: "none",
- system_shared_libs: [],
- srcs: [""],
- stubs: { versions: ["1"] },
- sanitize: {
- never: true,
- },
- } `)
- ctx := result.TestContext
- ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{
- "lib64/bionic/libc.so",
- "lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
- })
- hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared")
- installed := hwasan.Description("install libclang_rt.hwasan")
- ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
- symlink := hwasan.Description("install symlink libclang_rt.hwasan")
- ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so")
- ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so")
- }
- func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized(t *testing.T) {
- result := android.GroupFixturePreparers(
- prepareForTestOfRuntimeApexWithHwasan,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.SanitizeDevice = []string{"hwaddress"}
- }),
- ).RunTestWithBp(t, `
- cc_library {
- name: "libc",
- no_libcrt: true,
- nocrt: true,
- stl: "none",
- system_shared_libs: [],
- stubs: { versions: ["1"] },
- apex_available: ["com.android.runtime"],
- }
- cc_prebuilt_library_shared {
- name: "libclang_rt.hwasan-aarch64-android",
- no_libcrt: true,
- nocrt: true,
- stl: "none",
- system_shared_libs: [],
- srcs: [""],
- stubs: { versions: ["1"] },
- sanitize: {
- never: true,
- },
- }
- `)
- ctx := result.TestContext
- ensureExactContents(t, ctx, "com.android.runtime", "android_common_hwasan_com.android.runtime_image", []string{
- "lib64/bionic/libc.so",
- "lib64/bionic/libclang_rt.hwasan-aarch64-android.so",
- })
- hwasan := ctx.ModuleForTests("libclang_rt.hwasan-aarch64-android", "android_arm64_armv8-a_shared")
- installed := hwasan.Description("install libclang_rt.hwasan")
- ensureContains(t, installed.Output.String(), "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so")
- symlink := hwasan.Description("install symlink libclang_rt.hwasan")
- ensureEquals(t, symlink.Args["fromPath"], "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so")
- ensureContains(t, symlink.Output.String(), "/system/lib64/libclang_rt.hwasan-aarch64-android.so")
- }
- func TestApexDependsOnLLNDKTransitively(t *testing.T) {
- testcases := []struct {
- name string
- minSdkVersion string
- apexVariant string
- shouldLink string
- shouldNotLink []string
- }{
- {
- name: "unspecified version links to the latest",
- minSdkVersion: "",
- apexVariant: "apex10000",
- shouldLink: "current",
- shouldNotLink: []string{"29", "30"},
- },
- {
- name: "always use the latest",
- minSdkVersion: "min_sdk_version: \"29\",",
- apexVariant: "apex29",
- shouldLink: "current",
- shouldNotLink: []string{"29", "30"},
- },
- }
- for _, tc := range testcases {
- t.Run(tc.name, func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- `+tc.minSdkVersion+`
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- shared_libs: ["libbar"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- min_sdk_version: "29",
- }
- cc_library {
- name: "libbar",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: { versions: ["29","30"] },
- llndk: {
- symbol_file: "libbar.map.txt",
- }
- }
- `,
- withUnbundledBuild,
- )
- // Ensure that LLNDK dep is not included
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "lib64/mylib.so",
- })
- // Ensure that LLNDK dep is required
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
- ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
- ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_"+tc.apexVariant).Rule("ld").Args["libFlags"]
- ensureContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
- for _, ver := range tc.shouldNotLink {
- ensureNotContains(t, mylibLdFlags, "libbar/android_arm64_armv8-a_shared_"+ver+"/libbar.so")
- }
- mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
- ver := tc.shouldLink
- if tc.shouldLink == "current" {
- ver = strconv.Itoa(android.FutureApiLevelInt)
- }
- ensureContains(t, mylibCFlags, "__LIBBAR_API__="+ver)
- })
- }
- }
- func TestApexWithSystemLibsStubs(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "mylib_shared", "libdl", "libm"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: ["libc", "libm"],
- shared_libs: ["libdl#27"],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library_shared {
- name: "mylib_shared",
- srcs: ["mylib.cpp"],
- shared_libs: ["libdl#27"],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "libBootstrap",
- srcs: ["mylib.cpp"],
- stl: "none",
- bootstrap: true,
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that mylib, libm, libdl are included.
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- ensureContains(t, copyCmds, "image.apex/lib64/bionic/libm.so")
- ensureContains(t, copyCmds, "image.apex/lib64/bionic/libdl.so")
- // Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
- ensureNotContains(t, copyCmds, "image.apex/lib64/bionic/libc.so")
- mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
- mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
- mylibSharedCFlags := ctx.ModuleForTests("mylib_shared", "android_arm64_armv8-a_shared_apex10000").Rule("cc").Args["cFlags"]
- // For dependency to libc
- // Ensure that mylib is linking with the latest version of stubs
- ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_current/libc.so")
- // ... and not linking to the non-stub (impl) variant
- ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared/libc.so")
- // ... Cflags from stub is correctly exported to mylib
- ensureContains(t, mylibCFlags, "__LIBC_API__=10000")
- ensureContains(t, mylibSharedCFlags, "__LIBC_API__=10000")
- // For dependency to libm
- // Ensure that mylib is linking with the non-stub (impl) variant
- ensureContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_apex10000/libm.so")
- // ... and not linking to the stub variant
- ensureNotContains(t, mylibLdFlags, "libm/android_arm64_armv8-a_shared_29/libm.so")
- // ... and is not compiling with the stub
- ensureNotContains(t, mylibCFlags, "__LIBM_API__=29")
- ensureNotContains(t, mylibSharedCFlags, "__LIBM_API__=29")
- // For dependency to libdl
- // Ensure that mylib is linking with the specified version of stubs
- ensureContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_27/libdl.so")
- // ... and not linking to the other versions of stubs
- ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_28/libdl.so")
- ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_29/libdl.so")
- // ... and not linking to the non-stub (impl) variant
- ensureNotContains(t, mylibLdFlags, "libdl/android_arm64_armv8-a_shared_apex10000/libdl.so")
- // ... Cflags from stub is correctly exported to mylib
- ensureContains(t, mylibCFlags, "__LIBDL_API__=27")
- ensureContains(t, mylibSharedCFlags, "__LIBDL_API__=27")
- // Ensure that libBootstrap is depending on the platform variant of bionic libs
- libFlags := ctx.ModuleForTests("libBootstrap", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
- ensureContains(t, libFlags, "libc/android_arm64_armv8-a_shared/libc.so")
- ensureContains(t, libFlags, "libm/android_arm64_armv8-a_shared/libm.so")
- ensureContains(t, libFlags, "libdl/android_arm64_armv8-a_shared/libdl.so")
- }
- func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs(t *testing.T) {
- // there are three links between liba --> libz.
- // 1) myapex -> libx -> liba -> libz : this should be #30 link
- // 2) otherapex -> liby -> liba -> libz : this should be #30 link
- // 3) (platform) -> liba -> libz : this should be non-stub link
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libx"],
- min_sdk_version: "29",
- }
- apex {
- name: "otherapex",
- key: "myapex.key",
- native_shared_libs: ["liby"],
- min_sdk_version: "30",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libx",
- shared_libs: ["liba"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- min_sdk_version: "29",
- }
- cc_library {
- name: "liby",
- shared_libs: ["liba"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "otherapex" ],
- min_sdk_version: "29",
- }
- cc_library {
- name: "liba",
- shared_libs: ["libz"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "//apex_available:anyapex",
- "//apex_available:platform",
- ],
- min_sdk_version: "29",
- }
- cc_library {
- name: "libz",
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["28", "30"],
- },
- }
- `)
- expectLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectNoLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- // platform liba is linked to non-stub version
- expectLink("liba", "shared", "libz", "shared")
- // liba in myapex is linked to current
- expectLink("liba", "shared_apex29", "libz", "shared_current")
- expectNoLink("liba", "shared_apex29", "libz", "shared_30")
- expectNoLink("liba", "shared_apex29", "libz", "shared_28")
- expectNoLink("liba", "shared_apex29", "libz", "shared")
- // liba in otherapex is linked to current
- expectLink("liba", "shared_apex30", "libz", "shared_current")
- expectNoLink("liba", "shared_apex30", "libz", "shared_30")
- expectNoLink("liba", "shared_apex30", "libz", "shared_28")
- expectNoLink("liba", "shared_apex30", "libz", "shared")
- }
- func TestApexMinSdkVersion_SupportsCodeNames(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libx"],
- min_sdk_version: "R",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libx",
- shared_libs: ["libz"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- min_sdk_version: "R",
- }
- cc_library {
- name: "libz",
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["29", "R"],
- },
- }
- `,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_version_active_codenames = []string{"R"}
- }),
- )
- expectLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectNoLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectLink("libx", "shared_apex10000", "libz", "shared_current")
- expectNoLink("libx", "shared_apex10000", "libz", "shared_R")
- expectNoLink("libx", "shared_apex10000", "libz", "shared_29")
- expectNoLink("libx", "shared_apex10000", "libz", "shared")
- }
- func TestApexMinSdkVersion_SupportsCodeNames_JavaLibs(t *testing.T) {
- testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["libx"],
- min_sdk_version: "S",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "libx",
- srcs: ["a.java"],
- apex_available: [ "myapex" ],
- sdk_version: "current",
- min_sdk_version: "S", // should be okay
- }
- `,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_version_active_codenames = []string{"S"}
- variables.Platform_sdk_codename = proptools.StringPtr("S")
- }),
- )
- }
- func TestApexMinSdkVersion_DefaultsToLatest(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libx"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libx",
- shared_libs: ["libz"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "libz",
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1", "2"],
- },
- }
- `)
- expectLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectNoLink := func(from, from_variant, to, to_variant string) {
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectLink("libx", "shared_apex10000", "libz", "shared_current")
- expectNoLink("libx", "shared_apex10000", "libz", "shared_1")
- expectNoLink("libx", "shared_apex10000", "libz", "shared_2")
- expectNoLink("libx", "shared_apex10000", "libz", "shared")
- }
- func TestApexMinSdkVersion_crtobjectInVendorApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- vendor: true,
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- vendor_available: true,
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- min_sdk_version: "29",
- }
- `)
- vendorVariant := "android_vendor.29_arm64_armv8-a"
- // First check that the correct variant of crtbegin_so is used.
- ldRule := ctx.ModuleForTests("mylib", vendorVariant+"_shared_apex29").Rule("ld")
- crtBegin := names(ldRule.Args["crtBegin"])
- ensureListContains(t, crtBegin, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"crtbegin_so/"+vendorVariant+"_apex29/crtbegin_so.o")
- // Ensure that the crtbegin_so used by the APEX is targeting 29
- cflags := ctx.ModuleForTests("crtbegin_so", vendorVariant+"_apex29").Rule("cc").Args["cFlags"]
- android.AssertStringDoesContain(t, "cflags", cflags, "-target aarch64-linux-android29")
- }
- func TestPlatformUsesLatestStubsFromApexes(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libx"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libx",
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- stubs: {
- versions: ["1", "2"],
- },
- }
- cc_library {
- name: "libz",
- shared_libs: ["libx"],
- system_shared_libs: [],
- stl: "none",
- }
- `)
- expectLink := func(from, from_variant, to, to_variant string) {
- t.Helper()
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectNoLink := func(from, from_variant, to, to_variant string) {
- t.Helper()
- ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
- ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectLink("libz", "shared", "libx", "shared_current")
- expectNoLink("libz", "shared", "libx", "shared_2")
- expectNoLink("libz", "shared", "libz", "shared_1")
- expectNoLink("libz", "shared", "libz", "shared")
- }
- var prepareForTestWithSantitizeHwaddress = android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.SanitizeDevice = []string{"hwaddress"}
- },
- )
- func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libx"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libx",
- shared_libs: ["libbar"],
- apex_available: [ "myapex" ],
- min_sdk_version: "29",
- }
- cc_library {
- name: "libbar",
- stubs: {
- versions: ["29", "30"],
- },
- }
- `,
- prepareForTestWithSantitizeHwaddress,
- )
- expectLink := func(from, from_variant, to, to_variant string) {
- ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
- libFlags := ld.Args["libFlags"]
- ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_current")
- }
- func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libx"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libx",
- apex_available: [ "myapex" ],
- min_sdk_version: "29",
- }
- `)
- // ensure apex variant of c++ is linked with static unwinder
- cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_apex29").Module().(*cc.Module)
- ensureListContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind")
- // note that platform variant is not.
- cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
- ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libunwind")
- }
- func TestApexMinSdkVersion_ErrorIfIncompatibleVersion(t *testing.T) {
- testApexError(t, `module "mylib".*: should support min_sdk_version\(29\)`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- ],
- min_sdk_version: "30",
- }
- `)
- testApexError(t, `module "libfoo.ffi".*: should support min_sdk_version\(29\)`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo.ffi"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- rust_ffi_shared {
- name: "libfoo.ffi",
- srcs: ["foo.rs"],
- crate_name: "foo",
- apex_available: [
- "myapex",
- ],
- min_sdk_version: "30",
- }
- `)
- testApexError(t, `module "libfoo".*: should support min_sdk_version\(29\)`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["libfoo"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: [
- "myapex",
- ],
- min_sdk_version: "30",
- }
- `)
- }
- func TestApexMinSdkVersion_Okay(t *testing.T) {
- testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- java_libs: ["libbar"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- srcs: ["mylib.cpp"],
- shared_libs: ["libfoo_dep"],
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- cc_library {
- name: "libfoo_dep",
- srcs: ["mylib.cpp"],
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- java_library {
- name: "libbar",
- sdk_version: "current",
- srcs: ["a.java"],
- static_libs: [
- "libbar_dep",
- "libbar_import_dep",
- ],
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- java_library {
- name: "libbar_dep",
- sdk_version: "current",
- srcs: ["a.java"],
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- java_import {
- name: "libbar_import_dep",
- jars: ["libbar.jar"],
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- `)
- }
- func TestJavaStableSdkVersion(t *testing.T) {
- testCases := []struct {
- name string
- expectedError string
- bp string
- preparer android.FixturePreparer
- }{
- {
- name: "Non-updatable apex with non-stable dep",
- bp: `
- apex {
- name: "myapex",
- java_libs: ["myjar"],
- key: "myapex.key",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "test_current",
- apex_available: ["myapex"],
- }
- `,
- },
- {
- name: "Updatable apex with stable dep",
- bp: `
- apex {
- name: "myapex",
- java_libs: ["myjar"],
- key: "myapex.key",
- updatable: true,
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "current",
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- `,
- },
- {
- name: "Updatable apex with non-stable dep",
- expectedError: "cannot depend on \"myjar\"",
- bp: `
- apex {
- name: "myapex",
- java_libs: ["myjar"],
- key: "myapex.key",
- updatable: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "test_current",
- apex_available: ["myapex"],
- }
- `,
- },
- {
- name: "Updatable apex with non-stable legacy core platform dep",
- expectedError: `\Qcannot depend on "myjar-uses-legacy": non stable SDK core_platform_current - uses legacy core platform\E`,
- bp: `
- apex {
- name: "myapex",
- java_libs: ["myjar-uses-legacy"],
- key: "myapex.key",
- updatable: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "myjar-uses-legacy",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "core_platform",
- apex_available: ["myapex"],
- }
- `,
- preparer: java.FixtureUseLegacyCorePlatformApi("myjar-uses-legacy"),
- },
- {
- name: "Updatable apex with non-stable transitive dep",
- // This is not actually detecting that the transitive dependency is unstable, rather it is
- // detecting that the transitive dependency is building against a wider API surface than the
- // module that depends on it is using.
- expectedError: "compiles against Android API, but dependency \"transitive-jar\" is compiling against private API.",
- bp: `
- apex {
- name: "myapex",
- java_libs: ["myjar"],
- key: "myapex.key",
- updatable: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "current",
- apex_available: ["myapex"],
- static_libs: ["transitive-jar"],
- }
- java_library {
- name: "transitive-jar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "core_platform",
- apex_available: ["myapex"],
- }
- `,
- },
- }
- for _, test := range testCases {
- if test.name != "Updatable apex with non-stable legacy core platform dep" {
- continue
- }
- t.Run(test.name, func(t *testing.T) {
- errorHandler := android.FixtureExpectsNoErrors
- if test.expectedError != "" {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
- }
- android.GroupFixturePreparers(
- java.PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithApexBuildComponents,
- prepareForTestWithMyapex,
- android.OptionalFixturePreparer(test.preparer),
- ).
- ExtendWithErrorHandler(errorHandler).
- RunTestWithBp(t, test.bp)
- })
- }
- }
- func TestApexMinSdkVersion_ErrorIfDepIsNewer(t *testing.T) {
- testApexError(t, `module "mylib2".*: should support min_sdk_version\(29\) for "myapex"`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- ],
- min_sdk_version: "29",
- }
- // indirect part of the apex
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- ],
- min_sdk_version: "30",
- }
- `)
- }
- func TestApexMinSdkVersion_ErrorIfDepIsNewer_Java(t *testing.T) {
- testApexError(t, `module "bar".*: should support min_sdk_version\(29\) for "myapex"`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: ["AppFoo"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app {
- name: "AppFoo",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "current",
- min_sdk_version: "29",
- system_modules: "none",
- stl: "none",
- static_libs: ["bar"],
- apex_available: [ "myapex" ],
- }
- java_library {
- name: "bar",
- sdk_version: "current",
- srcs: ["a.java"],
- apex_available: [ "myapex" ],
- }
- `)
- }
- func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- // mylib in myapex will link to mylib2#current
- // mylib in otherapex will link to mylib2(non-stub) in otherapex as well
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
- system_shared_libs: [],
- stl: "none",
- apex_available: ["myapex", "otherapex"],
- min_sdk_version: "29",
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: ["otherapex"],
- stubs: { versions: ["29", "30"] },
- min_sdk_version: "30",
- }
- apex {
- name: "otherapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "mylib2"],
- min_sdk_version: "30",
- }
- `)
- expectLink := func(from, from_variant, to, to_variant string) {
- ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
- libFlags := ld.Args["libFlags"]
- ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
- }
- expectLink("mylib", "shared_apex29", "mylib2", "shared_current")
- expectLink("mylib", "shared_apex30", "mylib2", "shared_apex30")
- }
- func TestApexMinSdkVersion_WorksWithSdkCodename(t *testing.T) {
- withSAsActiveCodeNames := android.FixtureModifyProductVariables(
- func(variables android.FixtureProductVariables) {
- variables.Platform_sdk_codename = proptools.StringPtr("S")
- variables.Platform_version_active_codenames = []string{"S"}
- },
- )
- testApexError(t, `libbar.*: should support min_sdk_version\(S\)`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- min_sdk_version: "S",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- shared_libs: ["libbar"],
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- cc_library {
- name: "libbar",
- apex_available: ["myapex"],
- }
- `, withSAsActiveCodeNames)
- }
- func TestApexMinSdkVersion_WorksWithActiveCodenames(t *testing.T) {
- withSAsActiveCodeNames := android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_sdk_codename = proptools.StringPtr("S")
- variables.Platform_version_active_codenames = []string{"S", "T"}
- })
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- min_sdk_version: "S",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- shared_libs: ["libbar"],
- apex_available: ["myapex"],
- min_sdk_version: "S",
- }
- cc_library {
- name: "libbar",
- stubs: {
- symbol_file: "libbar.map.txt",
- versions: ["30", "S", "T"],
- },
- }
- `, withSAsActiveCodeNames)
- // ensure libfoo is linked with current version of libbar stub
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex10000")
- libFlags := libfoo.Rule("ld").Args["libFlags"]
- ensureContains(t, libFlags, "android_arm64_armv8-a_shared_current/libbar.so")
- }
- func TestFilesInSubDir(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- binaries: ["mybin"],
- prebuilts: ["myetc"],
- compile_multilib: "both",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- prebuilt_etc {
- name: "myetc",
- src: "myprebuilt",
- sub_dir: "foo/bar",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- relative_install_path: "foo/bar",
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_binary {
- name: "mybin",
- srcs: ["mylib.cpp"],
- relative_install_path: "foo/bar",
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- `)
- generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("generateFsConfig")
- cmd := generateFsRule.RuleParams.Command
- // Ensure that the subdirectories are all listed
- ensureContains(t, cmd, "/etc ")
- ensureContains(t, cmd, "/etc/foo ")
- ensureContains(t, cmd, "/etc/foo/bar ")
- ensureContains(t, cmd, "/lib64 ")
- ensureContains(t, cmd, "/lib64/foo ")
- ensureContains(t, cmd, "/lib64/foo/bar ")
- ensureContains(t, cmd, "/lib ")
- ensureContains(t, cmd, "/lib/foo ")
- ensureContains(t, cmd, "/lib/foo/bar ")
- ensureContains(t, cmd, "/bin ")
- ensureContains(t, cmd, "/bin/foo ")
- ensureContains(t, cmd, "/bin/foo/bar ")
- }
- func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- multilib: {
- both: {
- native_shared_libs: ["mylib"],
- binaries: ["mybin"],
- },
- },
- compile_multilib: "both",
- native_bridge_supported: true,
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- relative_install_path: "foo/bar",
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- native_bridge_supported: true,
- }
- cc_binary {
- name: "mybin",
- relative_install_path: "foo/bar",
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- native_bridge_supported: true,
- compile_multilib: "both", // default is "first" for binary
- multilib: {
- lib64: {
- suffix: "64",
- },
- },
- }
- `, withNativeBridgeEnabled)
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "bin/foo/bar/mybin",
- "bin/foo/bar/mybin64",
- "bin/arm/foo/bar/mybin",
- "bin/arm64/foo/bar/mybin64",
- "lib/foo/bar/mylib.so",
- "lib/arm/foo/bar/mylib.so",
- "lib64/foo/bar/mylib.so",
- "lib64/arm64/foo/bar/mylib.so",
- })
- }
- func TestVendorApex(t *testing.T) {
- result := android.GroupFixturePreparers(
- prepareForApexTest,
- android.FixtureModifyConfig(android.SetKatiEnabledForTests),
- ).RunTestWithBp(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- binaries: ["mybin"],
- vendor: true,
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_binary {
- name: "mybin",
- vendor: true,
- shared_libs: ["libfoo"],
- }
- cc_library {
- name: "libfoo",
- proprietary: true,
- }
- `)
- ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
- "bin/mybin",
- "lib64/libfoo.so",
- // TODO(b/159195575): Add an option to use VNDK libs from VNDK APEX
- "lib64/libc++.so",
- })
- apexBundle := result.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, result.TestContext, apexBundle)
- name := apexBundle.BaseModuleName()
- prefix := "TARGET_"
- var builder strings.Builder
- data.Custom(&builder, name, prefix, "", data)
- androidMk := android.StringRelativeToTop(result.Config, builder.String())
- installPath := "out/target/product/test_device/vendor/apex"
- ensureContains(t, androidMk, "LOCAL_MODULE_PATH := "+installPath)
- apexManifestRule := result.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
- requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
- ensureListNotContains(t, requireNativeLibs, ":vndk")
- }
- func TestVendorApex_use_vndk_as_stable(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- binaries: ["mybin"],
- vendor: true,
- use_vndk_as_stable: true,
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_binary {
- name: "mybin",
- vendor: true,
- shared_libs: ["libvndk", "libvendor"],
- }
- cc_library {
- name: "libvndk",
- vndk: {
- enabled: true,
- },
- vendor_available: true,
- product_available: true,
- }
- cc_library {
- name: "libvendor",
- vendor: true,
- }
- `)
- vendorVariant := "android_vendor.29_arm64_armv8-a"
- ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_apex10000").Rule("ld")
- libs := names(ldRule.Args["libFlags"])
- // VNDK libs(libvndk/libc++) as they are
- ensureListContains(t, libs, "out/soong/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
- ensureListContains(t, libs, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"libc++/"+vendorVariant+"_shared/libc++.so")
- // non-stable Vendor libs as APEX variants
- ensureListContains(t, libs, "out/soong/.intermediates/libvendor/"+vendorVariant+"_shared_apex10000/libvendor.so")
- // VNDK libs are not included when use_vndk_as_stable: true
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "bin/mybin",
- "lib64/libvendor.so",
- })
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
- requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
- ensureListContains(t, requireNativeLibs, ":vndk")
- }
- func TestProductVariant(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- product_specific: true,
- binaries: ["foo"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_binary {
- name: "foo",
- product_available: true,
- apex_available: ["myapex"],
- srcs: ["foo.cpp"],
- }
- `, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.ProductVndkVersion = proptools.StringPtr("current")
- }),
- )
- cflags := strings.Fields(
- ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"])
- ensureListContains(t, cflags, "-D__ANDROID_VNDK__")
- ensureListContains(t, cflags, "-D__ANDROID_APEX__")
- ensureListContains(t, cflags, "-D__ANDROID_PRODUCT__")
- ensureListNotContains(t, cflags, "-D__ANDROID_VENDOR__")
- }
- func TestApex_withPrebuiltFirmware(t *testing.T) {
- testCases := []struct {
- name string
- additionalProp string
- }{
- {"system apex with prebuilt_firmware", ""},
- {"vendor apex with prebuilt_firmware", "vendor: true,"},
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- prebuilts: ["myfirmware"],
- updatable: false,
- `+tc.additionalProp+`
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- prebuilt_firmware {
- name: "myfirmware",
- src: "myfirmware.bin",
- filename_from_src: true,
- `+tc.additionalProp+`
- }
- `)
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "etc/firmware/myfirmware.bin",
- })
- })
- }
- }
- func TestAndroidMk_VendorApexRequired(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- vendor: true,
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- vendor_available: true,
- }
- `)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- name := apexBundle.BaseModuleName()
- prefix := "TARGET_"
- var builder strings.Builder
- data.Custom(&builder, name, prefix, "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += libc.vendor libm.vendor libdl.vendor\n")
- }
- func TestAndroidMkWritesCommonProperties(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- vintf_fragments: ["fragment.xml"],
- init_rc: ["init.rc"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_binary {
- name: "mybin",
- }
- `)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- name := apexBundle.BaseModuleName()
- prefix := "TARGET_"
- var builder strings.Builder
- data.Custom(&builder, name, prefix, "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_FULL_VINTF_FRAGMENTS := fragment.xml\n")
- ensureContains(t, androidMk, "LOCAL_FULL_INIT_RC := init.rc\n")
- }
- func TestStaticLinking(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1", "2", "3"],
- },
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- cc_binary {
- name: "not_in_apex",
- srcs: ["mylib.cpp"],
- static_libs: ["mylib"],
- static_executable: true,
- system_shared_libs: [],
- stl: "none",
- }
- `)
- ldFlags := ctx.ModuleForTests("not_in_apex", "android_arm64_armv8-a").Rule("ld").Args["libFlags"]
- // Ensure that not_in_apex is linking with the static variant of mylib
- ensureContains(t, ldFlags, "mylib/android_arm64_armv8-a_static/mylib.a")
- }
- func TestKeys(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex_keytest",
- key: "myapex.key",
- certificate: ":myapex.certificate",
- native_shared_libs: ["mylib"],
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex_keytest" ],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app_certificate {
- name: "myapex.certificate",
- certificate: "testkey",
- }
- android_app_certificate {
- name: "myapex.certificate.override",
- certificate: "testkey.override",
- }
- `)
- // check the APEX keys
- keys := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey)
- if keys.publicKeyFile.String() != "vendor/foo/devkeys/testkey.avbpubkey" {
- t.Errorf("public key %q is not %q", keys.publicKeyFile.String(),
- "vendor/foo/devkeys/testkey.avbpubkey")
- }
- if keys.privateKeyFile.String() != "vendor/foo/devkeys/testkey.pem" {
- t.Errorf("private key %q is not %q", keys.privateKeyFile.String(),
- "vendor/foo/devkeys/testkey.pem")
- }
- // check the APK certs. It should be overridden to myapex.certificate.override
- certs := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk").Args["certificates"]
- if certs != "testkey.override.x509.pem testkey.override.pk8" {
- t.Errorf("cert and private key %q are not %q", certs,
- "testkey.override.509.pem testkey.override.pk8")
- }
- }
- func TestCertificate(t *testing.T) {
- t.Run("if unspecified, it defaults to DefaultAppCertificate", func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }`)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk")
- expected := "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8"
- if actual := rule.Args["certificates"]; actual != expected {
- t.Errorf("certificates should be %q, not %q", expected, actual)
- }
- })
- t.Run("override when unspecified", func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex_keytest",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app_certificate {
- name: "myapex.certificate.override",
- certificate: "testkey.override",
- }`)
- rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk")
- expected := "testkey.override.x509.pem testkey.override.pk8"
- if actual := rule.Args["certificates"]; actual != expected {
- t.Errorf("certificates should be %q, not %q", expected, actual)
- }
- })
- t.Run("if specified as :module, it respects the prop", func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- certificate: ":myapex.certificate",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app_certificate {
- name: "myapex.certificate",
- certificate: "testkey",
- }`)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk")
- expected := "testkey.x509.pem testkey.pk8"
- if actual := rule.Args["certificates"]; actual != expected {
- t.Errorf("certificates should be %q, not %q", expected, actual)
- }
- })
- t.Run("override when specifiec as <:module>", func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex_keytest",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- certificate: ":myapex.certificate",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app_certificate {
- name: "myapex.certificate.override",
- certificate: "testkey.override",
- }`)
- rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk")
- expected := "testkey.override.x509.pem testkey.override.pk8"
- if actual := rule.Args["certificates"]; actual != expected {
- t.Errorf("certificates should be %q, not %q", expected, actual)
- }
- })
- t.Run("if specified as name, finds it from DefaultDevKeyDir", func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- certificate: "testkey",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }`)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("signapk")
- expected := "vendor/foo/devkeys/testkey.x509.pem vendor/foo/devkeys/testkey.pk8"
- if actual := rule.Args["certificates"]; actual != expected {
- t.Errorf("certificates should be %q, not %q", expected, actual)
- }
- })
- t.Run("override when specified as <name>", func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex_keytest",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- certificate: "testkey",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app_certificate {
- name: "myapex.certificate.override",
- certificate: "testkey.override",
- }`)
- rule := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest_image").Rule("signapk")
- expected := "testkey.override.x509.pem testkey.override.pk8"
- if actual := rule.Args["certificates"]; actual != expected {
- t.Errorf("certificates should be %q, not %q", expected, actual)
- }
- })
- }
- func TestMacro(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "mylib2"],
- updatable: false,
- }
- apex {
- name: "otherapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "mylib2"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- "otherapex",
- ],
- recovery_available: true,
- min_sdk_version: "29",
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- "otherapex",
- ],
- static_libs: ["mylib3"],
- recovery_available: true,
- min_sdk_version: "29",
- }
- cc_library {
- name: "mylib3",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- "otherapex",
- ],
- recovery_available: true,
- min_sdk_version: "29",
- }
- `)
- // non-APEX variant does not have __ANDROID_APEX__ defined
- mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__")
- // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
- mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=10000")
- // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
- mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=29")
- // When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and
- // each variant defines additional macros to distinguish which apex variant it is built for
- // non-APEX variant does not have __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- // recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
- mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__")
- // non-APEX variant does not have __ANDROID_APEX__ defined
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- // recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
- mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__")
- }
- func TestHeaderLibsDependency(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library_headers {
- name: "mylib_headers",
- export_include_dirs: ["my_include"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- header_libs: ["mylib_headers"],
- export_header_lib_headers: ["mylib_headers"],
- stubs: {
- versions: ["1", "2", "3"],
- },
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "otherlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- shared_libs: ["mylib"],
- }
- `)
- cFlags := ctx.ModuleForTests("otherlib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
- // Ensure that the include path of the header lib is exported to 'otherlib'
- ensureContains(t, cFlags, "-Imy_include")
- }
- type fileInApex struct {
- path string // path in apex
- src string // src path
- isLink bool
- }
- func getFiles(t *testing.T, ctx *android.TestContext, moduleName, variant string) []fileInApex {
- t.Helper()
- apexRule := ctx.ModuleForTests(moduleName, variant).Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- imageApexDir := "/image.apex/"
- var ret []fileInApex
- for _, cmd := range strings.Split(copyCmds, "&&") {
- cmd = strings.TrimSpace(cmd)
- if cmd == "" {
- continue
- }
- terms := strings.Split(cmd, " ")
- var dst, src string
- var isLink bool
- switch terms[0] {
- case "mkdir":
- case "cp":
- if len(terms) != 3 && len(terms) != 4 {
- t.Fatal("copyCmds contains invalid cp command", cmd)
- }
- dst = terms[len(terms)-1]
- src = terms[len(terms)-2]
- isLink = false
- case "ln":
- if len(terms) != 3 && len(terms) != 4 {
- // ln LINK TARGET or ln -s LINK TARGET
- t.Fatal("copyCmds contains invalid ln command", cmd)
- }
- dst = terms[len(terms)-1]
- src = terms[len(terms)-2]
- isLink = true
- default:
- t.Fatalf("copyCmds should contain mkdir/cp commands only: %q", cmd)
- }
- if dst != "" {
- index := strings.Index(dst, imageApexDir)
- if index == -1 {
- t.Fatal("copyCmds should copy a file to image.apex/", cmd)
- }
- dstFile := dst[index+len(imageApexDir):]
- ret = append(ret, fileInApex{path: dstFile, src: src, isLink: isLink})
- }
- }
- return ret
- }
- func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, variant string, files []string) {
- t.Helper()
- var failed bool
- var surplus []string
- filesMatched := make(map[string]bool)
- for _, file := range getFiles(t, ctx, moduleName, variant) {
- mactchFound := false
- for _, expected := range files {
- if matched, _ := path.Match(expected, file.path); matched {
- filesMatched[expected] = true
- mactchFound = true
- break
- }
- }
- if !mactchFound {
- surplus = append(surplus, file.path)
- }
- }
- if len(surplus) > 0 {
- sort.Strings(surplus)
- t.Log("surplus files", surplus)
- failed = true
- }
- if len(files) > len(filesMatched) {
- var missing []string
- for _, expected := range files {
- if !filesMatched[expected] {
- missing = append(missing, expected)
- }
- }
- sort.Strings(missing)
- t.Log("missing files", missing)
- failed = true
- }
- if failed {
- t.Fail()
- }
- }
- func TestVndkApexCurrent(t *testing.T) {
- commonFiles := []string{
- "lib/libc++.so",
- "lib64/libc++.so",
- "etc/llndk.libraries.29.txt",
- "etc/vndkcore.libraries.29.txt",
- "etc/vndksp.libraries.29.txt",
- "etc/vndkprivate.libraries.29.txt",
- "etc/vndkproduct.libraries.29.txt",
- }
- testCases := []struct {
- vndkVersion string
- expectedFiles []string
- }{
- {
- vndkVersion: "current",
- expectedFiles: append(commonFiles,
- "lib/libvndk.so",
- "lib/libvndksp.so",
- "lib64/libvndk.so",
- "lib64/libvndksp.so"),
- },
- {
- vndkVersion: "",
- expectedFiles: append(commonFiles,
- // Legacy VNDK APEX contains only VNDK-SP files (of core variant)
- "lib/libvndksp.so",
- "lib64/libvndksp.so"),
- },
- }
- for _, tc := range testCases {
- t.Run("VNDK.current with DeviceVndkVersion="+tc.vndkVersion, func(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- updatable: false,
- }
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- cc_library {
- name: "libvndksp",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- // VNDK-Ext should not cause any problems
- cc_library {
- name: "libvndk.ext",
- srcs: ["mylib2.cpp"],
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- system_shared_libs: [],
- stl: "none",
- }
- cc_library {
- name: "libvndksp.ext",
- srcs: ["mylib2.cpp"],
- vendor: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- extends: "libvndksp",
- },
- system_shared_libs: [],
- stl: "none",
- }
- `+vndkLibrariesTxtFiles("current"), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = proptools.StringPtr(tc.vndkVersion)
- }))
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", tc.expectedFiles)
- })
- }
- }
- func TestVndkApexWithPrebuilt(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- updatable: false,
- }
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_prebuilt_library_shared {
- name: "libvndk",
- srcs: ["libvndk.so"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- cc_prebuilt_library_shared {
- name: "libvndk.arm",
- srcs: ["libvndk.arm.so"],
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- enabled: false,
- arch: {
- arm: {
- enabled: true,
- },
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- `+vndkLibrariesTxtFiles("current"),
- withFiles(map[string][]byte{
- "libvndk.so": nil,
- "libvndk.arm.so": nil,
- }))
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
- "lib/libvndk.so",
- "lib/libvndk.arm.so",
- "lib64/libvndk.so",
- "lib/libc++.so",
- "lib64/libc++.so",
- "etc/*",
- })
- }
- func vndkLibrariesTxtFiles(vers ...string) (result string) {
- for _, v := range vers {
- if v == "current" {
- for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate", "vndkproduct"} {
- result += `
- ` + txt + `_libraries_txt {
- name: "` + txt + `.libraries.txt",
- }
- `
- }
- } else {
- for _, txt := range []string{"llndk", "vndkcore", "vndksp", "vndkprivate", "vndkproduct"} {
- result += `
- prebuilt_etc {
- name: "` + txt + `.libraries.` + v + `.txt",
- src: "dummy.txt",
- }
- `
- }
- }
- }
- return
- }
- func TestVndkApexVersion(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.v27",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- vndk_version: "27",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- vndk_prebuilt_shared {
- name: "libvndk27",
- version: "27",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- target_arch: "arm64",
- arch: {
- arm: {
- srcs: ["libvndk27_arm.so"],
- },
- arm64: {
- srcs: ["libvndk27_arm64.so"],
- },
- },
- apex_available: [ "com.android.vndk.v27" ],
- }
- vndk_prebuilt_shared {
- name: "libvndk27",
- version: "27",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- target_arch: "x86_64",
- arch: {
- x86: {
- srcs: ["libvndk27_x86.so"],
- },
- x86_64: {
- srcs: ["libvndk27_x86_64.so"],
- },
- },
- }
- `+vndkLibrariesTxtFiles("27"),
- withFiles(map[string][]byte{
- "libvndk27_arm.so": nil,
- "libvndk27_arm64.so": nil,
- "libvndk27_x86.so": nil,
- "libvndk27_x86_64.so": nil,
- }))
- ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common_image", []string{
- "lib/libvndk27_arm.so",
- "lib64/libvndk27_arm64.so",
- "etc/*",
- })
- }
- func TestVndkApexNameRule(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex_vndk {
- name: "com.android.vndk.v28",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- vndk_version: "28",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }`+vndkLibrariesTxtFiles("28", "current"))
- assertApexName := func(expected, moduleName string) {
- bundle := ctx.ModuleForTests(moduleName, "android_common_image").Module().(*apexBundle)
- actual := proptools.String(bundle.properties.Apex_name)
- if !reflect.DeepEqual(actual, expected) {
- t.Errorf("Got '%v', expected '%v'", actual, expected)
- }
- }
- assertApexName("com.android.vndk.v29", "com.android.vndk.current")
- assertApexName("com.android.vndk.v28", "com.android.vndk.v28")
- }
- func TestVndkApexSkipsNativeBridgeSupportedModules(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- native_bridge_supported: true,
- host_supported: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "com.android.vndk.current" ],
- }
- `+vndkLibrariesTxtFiles("current"),
- withNativeBridgeEnabled)
- ensureExactContents(t, ctx, "com.android.vndk.current", "android_common_image", []string{
- "lib/libvndk.so",
- "lib64/libvndk.so",
- "lib/libc++.so",
- "lib64/libc++.so",
- "etc/*",
- })
- }
- func TestVndkApexDoesntSupportNativeBridgeSupported(t *testing.T) {
- testApexError(t, `module "com.android.vndk.current" .*: native_bridge_supported: .* doesn't support native bridge binary`, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- file_contexts: ":myapex-file_contexts",
- native_bridge_supported: true,
- }
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libvndk",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- product_available: true,
- native_bridge_supported: true,
- host_supported: true,
- vndk: {
- enabled: true,
- },
- system_shared_libs: [],
- stl: "none",
- }
- `)
- }
- func TestVndkApexWithBinder32(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.v27",
- key: "myapex.key",
- file_contexts: ":myapex-file_contexts",
- vndk_version: "27",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- vndk_prebuilt_shared {
- name: "libvndk27",
- version: "27",
- target_arch: "arm",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm: {
- srcs: ["libvndk27.so"],
- }
- },
- }
- vndk_prebuilt_shared {
- name: "libvndk27",
- version: "27",
- target_arch: "arm",
- binder32bit: true,
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- arch: {
- arm: {
- srcs: ["libvndk27binder32.so"],
- }
- },
- apex_available: [ "com.android.vndk.v27" ],
- }
- `+vndkLibrariesTxtFiles("27"),
- withFiles(map[string][]byte{
- "libvndk27.so": nil,
- "libvndk27binder32.so": nil,
- }),
- withBinder32bit,
- withTargets(map[android.OsType][]android.Target{
- android.Android: []android.Target{
- {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
- NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
- },
- }),
- )
- ensureExactContents(t, ctx, "com.android.vndk.v27", "android_common_image", []string{
- "lib/libvndk27binder32.so",
- "etc/*",
- })
- }
- func TestVndkApexShouldNotProvideNativeLibs(t *testing.T) {
- ctx := testApex(t, `
- apex_vndk {
- name: "com.android.vndk.current",
- key: "com.android.vndk.current.key",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex_key {
- name: "com.android.vndk.current.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libz",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- stubs: {
- symbol_file: "libz.map.txt",
- versions: ["30"],
- }
- }
- `+vndkLibrariesTxtFiles("current"), withFiles(map[string][]byte{
- "libz.map.txt": nil,
- }))
- apexManifestRule := ctx.ModuleForTests("com.android.vndk.current", "android_common_image").Rule("apexManifestRule")
- provideNativeLibs := names(apexManifestRule.Args["provideNativeLibs"])
- ensureListEmpty(t, provideNativeLibs)
- }
- func TestDependenciesInApexManifest(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex_nodep",
- key: "myapex.key",
- native_shared_libs: ["lib_nodep"],
- compile_multilib: "both",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex {
- name: "myapex_dep",
- key: "myapex.key",
- native_shared_libs: ["lib_dep"],
- compile_multilib: "both",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex {
- name: "myapex_provider",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- compile_multilib: "both",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex {
- name: "myapex_selfcontained",
- key: "myapex.key",
- native_shared_libs: ["lib_dep", "libfoo"],
- compile_multilib: "both",
- file_contexts: ":myapex-file_contexts",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "lib_nodep",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex_nodep" ],
- }
- cc_library {
- name: "lib_dep",
- srcs: ["mylib.cpp"],
- shared_libs: ["libfoo"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex_dep",
- "myapex_provider",
- "myapex_selfcontained",
- ],
- }
- cc_library {
- name: "libfoo",
- srcs: ["mytest.cpp"],
- stubs: {
- versions: ["1"],
- },
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex_provider",
- "myapex_selfcontained",
- ],
- }
- `)
- var apexManifestRule android.TestingBuildParams
- var provideNativeLibs, requireNativeLibs []string
- apexManifestRule = ctx.ModuleForTests("myapex_nodep", "android_common_myapex_nodep_image").Rule("apexManifestRule")
- provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
- requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
- ensureListEmpty(t, provideNativeLibs)
- ensureListEmpty(t, requireNativeLibs)
- apexManifestRule = ctx.ModuleForTests("myapex_dep", "android_common_myapex_dep_image").Rule("apexManifestRule")
- provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
- requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
- ensureListEmpty(t, provideNativeLibs)
- ensureListContains(t, requireNativeLibs, "libfoo.so")
- apexManifestRule = ctx.ModuleForTests("myapex_provider", "android_common_myapex_provider_image").Rule("apexManifestRule")
- provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
- requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
- ensureListContains(t, provideNativeLibs, "libfoo.so")
- ensureListEmpty(t, requireNativeLibs)
- apexManifestRule = ctx.ModuleForTests("myapex_selfcontained", "android_common_myapex_selfcontained_image").Rule("apexManifestRule")
- provideNativeLibs = names(apexManifestRule.Args["provideNativeLibs"])
- requireNativeLibs = names(apexManifestRule.Args["requireNativeLibs"])
- ensureListContains(t, provideNativeLibs, "libfoo.so")
- ensureListEmpty(t, requireNativeLibs)
- }
- func TestApexName(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apex_name: "com.android.myapex",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_com.android.myapex_image")
- apexManifestRule := module.Rule("apexManifestRule")
- ensureContains(t, apexManifestRule.Args["opt"], "-v name com.android.myapex")
- apexRule := module.Rule("apexRule")
- ensureContains(t, apexRule.Args["opt_flags"], "--do_not_check_keyname")
- apexBundle := module.Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- name := apexBundle.BaseModuleName()
- prefix := "TARGET_"
- var builder strings.Builder
- data.Custom(&builder, name, prefix, "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
- }
- func TestNonTestApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib_common"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib_common",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule := module.Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- if apex, ok := module.Module().(*apexBundle); !ok || apex.testApex {
- t.Log("Apex was a test apex!")
- t.Fail()
- }
- // Ensure that main rule creates an output
- ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
- // Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that both direct and indirect deps are copied into apex
- ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
- // Ensure that the platform variant ends with _shared
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared")
- if !ctx.ModuleForTests("mylib_common", "android_arm64_armv8-a_shared_apex10000").Module().(*cc.Module).InAnyApex() {
- t.Log("Found mylib_common not in any apex!")
- t.Fail()
- }
- }
- func TestTestApex(t *testing.T) {
- ctx := testApex(t, `
- apex_test {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib_common_test"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib_common_test",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule := module.Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- if apex, ok := module.Module().(*apexBundle); !ok || !apex.testApex {
- t.Log("Apex was not a test apex!")
- t.Fail()
- }
- // Ensure that main rule creates an output
- ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
- // Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that both direct and indirect deps are copied into apex
- ensureContains(t, copyCmds, "image.apex/lib64/mylib_common_test.so")
- // Ensure that the platform variant ends with _shared
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common_test"), "android_arm64_armv8-a_shared")
- }
- func TestApexWithTarget(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- multilib: {
- first: {
- native_shared_libs: ["mylib_common"],
- }
- },
- target: {
- android: {
- multilib: {
- first: {
- native_shared_libs: ["mylib"],
- }
- }
- },
- host: {
- multilib: {
- first: {
- native_shared_libs: ["mylib2"],
- }
- }
- }
- }
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- cc_library {
- name: "mylib_common",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- compile_multilib: "first",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- compile_multilib: "first",
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that main rule creates an output
- ensureContains(t, apexRule.Output.String(), "myapex.apex.unsigned")
- // Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_apex10000")
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared_apex10000")
- ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that both direct and indirect deps are copied into apex
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- ensureContains(t, copyCmds, "image.apex/lib64/mylib_common.so")
- ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
- // Ensure that the platform variant ends with _shared
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared")
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared")
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared")
- }
- func TestApexWithArch(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- arch: {
- arm64: {
- native_shared_libs: ["mylib.arm64"],
- },
- x86_64: {
- native_shared_libs: ["mylib.x64"],
- },
- }
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib.arm64",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- cc_library {
- name: "mylib.x64",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- // TODO: remove //apex_available:platform
- apex_available: [
- "//apex_available:platform",
- "myapex",
- ],
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that apex variant is created for the direct dep
- ensureListContains(t, ctx.ModuleVariantsForTests("mylib.arm64"), "android_arm64_armv8-a_shared_apex10000")
- ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib.x64"), "android_arm64_armv8-a_shared_apex10000")
- // Ensure that both direct and indirect deps are copied into apex
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.arm64.so")
- ensureNotContains(t, copyCmds, "image.apex/lib64/mylib.x64.so")
- }
- func TestApexWithShBinary(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- sh_binaries: ["myscript"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- sh_binary {
- name: "myscript",
- src: "mylib.cpp",
- filename: "myscript.sh",
- sub_dir: "script",
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/bin/script/myscript.sh")
- }
- func TestApexInVariousPartition(t *testing.T) {
- testcases := []struct {
- propName, parition, flattenedPartition string
- }{
- {"", "system", "system_ext"},
- {"product_specific: true", "product", "product"},
- {"soc_specific: true", "vendor", "vendor"},
- {"proprietary: true", "vendor", "vendor"},
- {"vendor: true", "vendor", "vendor"},
- {"system_ext_specific: true", "system_ext", "system_ext"},
- }
- for _, tc := range testcases {
- t.Run(tc.propName+":"+tc.parition, func(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- `+tc.propName+`
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- apex := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- expected := "out/soong/target/product/test_device/" + tc.parition + "/apex"
- actual := apex.installDir.RelativeToTop().String()
- if actual != expected {
- t.Errorf("wrong install path. expected %q. actual %q", expected, actual)
- }
- flattened := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
- expected = "out/soong/target/product/test_device/" + tc.flattenedPartition + "/apex"
- actual = flattened.installDir.RelativeToTop().String()
- if actual != expected {
- t.Errorf("wrong install path. expected %q. actual %q", expected, actual)
- }
- })
- }
- }
- func TestFileContexts_FindInDefaultLocationIfNotSet(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- rule := module.Output("file_contexts")
- ensureContains(t, rule.RuleParams.Command, "cat system/sepolicy/apex/myapex-file_contexts")
- }
- func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes(t *testing.T) {
- testApexError(t, `"myapex" .*: file_contexts: should be under system/sepolicy`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- file_contexts: "my_own_file_contexts",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `, withFiles(map[string][]byte{
- "my_own_file_contexts": nil,
- }))
- }
- func TestFileContexts_ProductSpecificApexes(t *testing.T) {
- testApexError(t, `"myapex" .*: file_contexts: cannot find`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- product_specific: true,
- file_contexts: "product_specific_file_contexts",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- product_specific: true,
- file_contexts: "product_specific_file_contexts",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `, withFiles(map[string][]byte{
- "product_specific_file_contexts": nil,
- }))
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- rule := module.Output("file_contexts")
- ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
- }
- func TestFileContexts_SetViaFileGroup(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- product_specific: true,
- file_contexts: ":my-file-contexts",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- filegroup {
- name: "my-file-contexts",
- srcs: ["product_specific_file_contexts"],
- }
- `, withFiles(map[string][]byte{
- "product_specific_file_contexts": nil,
- }))
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- rule := module.Output("file_contexts")
- ensureContains(t, rule.RuleParams.Command, "cat product_specific_file_contexts")
- }
- func TestApexKeyFromOtherModule(t *testing.T) {
- ctx := testApex(t, `
- apex_key {
- name: "myapex.key",
- public_key: ":my.avbpubkey",
- private_key: ":my.pem",
- product_specific: true,
- }
- filegroup {
- name: "my.avbpubkey",
- srcs: ["testkey2.avbpubkey"],
- }
- filegroup {
- name: "my.pem",
- srcs: ["testkey2.pem"],
- }
- `)
- apex_key := ctx.ModuleForTests("myapex.key", "android_common").Module().(*apexKey)
- expected_pubkey := "testkey2.avbpubkey"
- actual_pubkey := apex_key.publicKeyFile.String()
- if actual_pubkey != expected_pubkey {
- t.Errorf("wrong public key path. expected %q. actual %q", expected_pubkey, actual_pubkey)
- }
- expected_privkey := "testkey2.pem"
- actual_privkey := apex_key.privateKeyFile.String()
- if actual_privkey != expected_privkey {
- t.Errorf("wrong private key path. expected %q. actual %q", expected_privkey, actual_privkey)
- }
- }
- func TestPrebuilt(t *testing.T) {
- ctx := testApex(t, `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- }
- `)
- prebuilt := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*Prebuilt)
- expectedInput := "myapex-arm64.apex"
- if prebuilt.inputApex.String() != expectedInput {
- t.Errorf("inputApex invalid. expected: %q, actual: %q", expectedInput, prebuilt.inputApex.String())
- }
- }
- func TestPrebuiltMissingSrc(t *testing.T) {
- testApexError(t, `module "myapex" variant "android_common_myapex".*: prebuilt_apex does not support "arm64_armv8-a"`, `
- prebuilt_apex {
- name: "myapex",
- }
- `)
- }
- func TestPrebuiltFilenameOverride(t *testing.T) {
- ctx := testApex(t, `
- prebuilt_apex {
- name: "myapex",
- src: "myapex-arm.apex",
- filename: "notmyapex.apex",
- }
- `)
- p := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*Prebuilt)
- expected := "notmyapex.apex"
- if p.installFilename != expected {
- t.Errorf("installFilename invalid. expected: %q, actual: %q", expected, p.installFilename)
- }
- }
- func TestApexSetFilenameOverride(t *testing.T) {
- testApex(t, `
- apex_set {
- name: "com.company.android.myapex",
- apex_name: "com.android.myapex",
- set: "company-myapex.apks",
- filename: "com.company.android.myapex.apex"
- }
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
- testApex(t, `
- apex_set {
- name: "com.company.android.myapex",
- apex_name: "com.android.myapex",
- set: "company-myapex.apks",
- filename: "com.company.android.myapex.capex"
- }
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
- testApexError(t, `filename should end in .apex or .capex for apex_set`, `
- apex_set {
- name: "com.company.android.myapex",
- apex_name: "com.android.myapex",
- set: "company-myapex.apks",
- filename: "some-random-suffix"
- }
- `)
- }
- func TestPrebuiltOverrides(t *testing.T) {
- ctx := testApex(t, `
- prebuilt_apex {
- name: "myapex.prebuilt",
- src: "myapex-arm.apex",
- overrides: [
- "myapex",
- ],
- }
- `)
- p := ctx.ModuleForTests("myapex.prebuilt", "android_common_myapex.prebuilt").Module().(*Prebuilt)
- expected := []string{"myapex"}
- actual := android.AndroidMkEntriesForTest(t, ctx, p)[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
- if !reflect.DeepEqual(actual, expected) {
- t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES value '%s', expected '%s'", actual, expected)
- }
- }
- func TestPrebuiltApexName(t *testing.T) {
- testApex(t, `
- prebuilt_apex {
- name: "com.company.android.myapex",
- apex_name: "com.android.myapex",
- src: "company-myapex-arm.apex",
- }
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
- testApex(t, `
- apex_set {
- name: "com.company.android.myapex",
- apex_name: "com.android.myapex",
- set: "company-myapex.apks",
- }
- `).ModuleForTests("com.company.android.myapex", "android_common_com.android.myapex")
- }
- func TestPrebuiltApexNameWithPlatformBootclasspath(t *testing.T) {
- _ = android.GroupFixturePreparers(
- java.PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithApexBuildComponents,
- android.FixtureWithRootAndroidBp(`
- platform_bootclasspath {
- name: "platform-bootclasspath",
- fragments: [
- {
- apex: "com.android.art",
- module: "art-bootclasspath-fragment",
- },
- ],
- }
- prebuilt_apex {
- name: "com.company.android.art",
- apex_name: "com.android.art",
- src: "com.company.android.art-arm.apex",
- exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "art-bootclasspath-fragment",
- image_name: "art",
- contents: ["core-oj"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
- },
- }
- java_import {
- name: "core-oj",
- jars: ["prebuilt.jar"],
- }
- `),
- ).RunTest(t)
- }
- // These tests verify that the prebuilt_apex/deapexer to java_import wiring allows for the
- // propagation of paths to dex implementation jars from the former to the latter.
- func TestPrebuiltExportDexImplementationJars(t *testing.T) {
- transform := android.NullFixturePreparer
- checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) {
- t.Helper()
- // Make sure the import has been given the correct path to the dex jar.
- p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
- dexJarBuildPath := p.DexJarBuildPath().PathOrNil()
- stem := android.RemoveOptionalPrebuiltPrefix(name)
- android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.",
- ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar",
- android.NormalizePathForTesting(dexJarBuildPath))
- }
- checkDexJarInstallPath := func(t *testing.T, ctx *android.TestContext, name string) {
- t.Helper()
- // Make sure the import has been given the correct path to the dex jar.
- p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency)
- dexJarBuildPath := p.DexJarInstallPath()
- stem := android.RemoveOptionalPrebuiltPrefix(name)
- android.AssertStringEquals(t, "DexJarInstallPath should be apex-related path.",
- "target/product/test_device/apex/myapex/javalib/"+stem+".jar",
- android.NormalizePathForTesting(dexJarBuildPath))
- }
- ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) {
- t.Helper()
- // Make sure that an apex variant is not created for the source module.
- android.AssertArrayString(t, "Check if there is no source variant",
- []string{"android_common"},
- ctx.ModuleVariantsForTests(name))
- }
- t.Run("prebuilt only", func(t *testing.T) {
- bp := `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_java_libs: ["libfoo", "libbar"],
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- }
- java_sdk_library_import {
- name: "libbar",
- public: {
- jars: ["libbar.jar"],
- },
- }
- `
- // Make sure that dexpreopt can access dex implementation files from the prebuilt.
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
- deapexerName := deapexerModuleName("myapex")
- android.AssertStringEquals(t, "APEX module name from deapexer name", "myapex", apexModuleName(deapexerName))
- // Make sure that the deapexer has the correct input APEX.
- deapexer := ctx.ModuleForTests(deapexerName, "android_common")
- rule := deapexer.Rule("deapexer")
- if expected, actual := []string{"myapex-arm64.apex"}, android.NormalizePathsForTesting(rule.Implicits); !reflect.DeepEqual(expected, actual) {
- t.Errorf("expected: %q, found: %q", expected, actual)
- }
- // Make sure that the prebuilt_apex has the correct input APEX.
- prebuiltApex := ctx.ModuleForTests("myapex", "android_common_myapex")
- rule = prebuiltApex.Rule("android/soong/android.Cp")
- if expected, actual := "myapex-arm64.apex", android.NormalizePathForTesting(rule.Input); !reflect.DeepEqual(expected, actual) {
- t.Errorf("expected: %q, found: %q", expected, actual)
- }
- checkDexJarBuildPath(t, ctx, "libfoo")
- checkDexJarInstallPath(t, ctx, "libfoo")
- checkDexJarBuildPath(t, ctx, "libbar")
- checkDexJarInstallPath(t, ctx, "libbar")
- })
- t.Run("prebuilt with source preferred", func(t *testing.T) {
- bp := `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_java_libs: ["libfoo", "libbar"],
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- }
- java_library {
- name: "libfoo",
- }
- java_sdk_library_import {
- name: "libbar",
- public: {
- jars: ["libbar.jar"],
- },
- }
- java_sdk_library {
- name: "libbar",
- srcs: ["foo/bar/MyClass.java"],
- unsafe_ignore_missing_latest_api: true,
- }
- `
- // Make sure that dexpreopt can access dex implementation files from the prebuilt.
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
- checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
- ensureNoSourceVariant(t, ctx, "libfoo")
- checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
- checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
- ensureNoSourceVariant(t, ctx, "libbar")
- })
- t.Run("prebuilt preferred with source", func(t *testing.T) {
- bp := `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_java_libs: ["libfoo", "libbar"],
- }
- java_import {
- name: "libfoo",
- prefer: true,
- jars: ["libfoo.jar"],
- }
- java_library {
- name: "libfoo",
- }
- java_sdk_library_import {
- name: "libbar",
- prefer: true,
- public: {
- jars: ["libbar.jar"],
- },
- }
- java_sdk_library {
- name: "libbar",
- srcs: ["foo/bar/MyClass.java"],
- unsafe_ignore_missing_latest_api: true,
- }
- `
- // Make sure that dexpreopt can access dex implementation files from the prebuilt.
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkDexJarBuildPath(t, ctx, "prebuilt_libfoo")
- checkDexJarInstallPath(t, ctx, "prebuilt_libfoo")
- ensureNoSourceVariant(t, ctx, "libfoo")
- checkDexJarBuildPath(t, ctx, "prebuilt_libbar")
- checkDexJarInstallPath(t, ctx, "prebuilt_libbar")
- ensureNoSourceVariant(t, ctx, "libbar")
- })
- }
- func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
- preparer := android.GroupFixturePreparers(
- java.FixtureConfigureApexBootJars("myapex:libfoo", "myapex:libbar"),
- // Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
- // is disabled.
- android.FixtureAddTextFile("frameworks/base/Android.bp", ""),
- )
- checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
- t.Helper()
- s := ctx.ModuleForTests("platform-bootclasspath", "android_common")
- foundLibfooJar := false
- base := stem + ".jar"
- for _, output := range s.AllOutputs() {
- if filepath.Base(output) == base {
- foundLibfooJar = true
- buildRule := s.Output(output)
- android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String())
- }
- }
- if !foundLibfooJar {
- t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().SoongOutDir(), s.AllOutputs()))
- }
- }
- checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
- t.Helper()
- platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
- var rule android.TestingBuildParams
- rule = platformBootclasspath.Output("hiddenapi-monolithic/index-from-classes.csv")
- java.CheckHiddenAPIRuleInputs(t, "intermediate index", expectedIntermediateInputs, rule)
- }
- checkHiddenAPIIndexFromFlagsInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
- t.Helper()
- platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
- var rule android.TestingBuildParams
- rule = platformBootclasspath.Output("hiddenapi-index.csv")
- java.CheckHiddenAPIRuleInputs(t, "monolithic index", expectedIntermediateInputs, rule)
- }
- fragment := java.ApexVariantReference{
- Apex: proptools.StringPtr("myapex"),
- Module: proptools.StringPtr("my-bootclasspath-fragment"),
- }
- t.Run("prebuilt only", func(t *testing.T) {
- bp := `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- contents: ["libfoo", "libbar"],
- apex_available: ["myapex"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
- filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
- filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
- },
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: ["myapex"],
- permitted_packages: ["foo"],
- }
- java_sdk_library_import {
- name: "libbar",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["myapex"],
- shared_library: false,
- permitted_packages: ["bar"],
- }
- `
- ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
- checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
- my-bootclasspath-fragment/index.csv
- out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- `)
- })
- t.Run("apex_set only", func(t *testing.T) {
- bp := `
- apex_set {
- name: "myapex",
- set: "myapex.apks",
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- contents: ["libfoo", "libbar"],
- apex_available: ["myapex"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
- filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
- filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
- },
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: ["myapex"],
- permitted_packages: ["foo"],
- }
- java_sdk_library_import {
- name: "libbar",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["myapex"],
- shared_library: false,
- permitted_packages: ["bar"],
- }
- `
- ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
- checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
- my-bootclasspath-fragment/index.csv
- out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- `)
- })
- t.Run("prebuilt with source library preferred", func(t *testing.T) {
- bp := `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- contents: ["libfoo", "libbar"],
- apex_available: ["myapex"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
- all_flags: "my-bootclasspath-fragment/all-flags.csv",
- },
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: ["myapex"],
- }
- java_library {
- name: "libfoo",
- srcs: ["foo/bar/MyClass.java"],
- apex_available: ["myapex"],
- }
- java_sdk_library_import {
- name: "libbar",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["myapex"],
- shared_library: false,
- }
- java_sdk_library {
- name: "libbar",
- srcs: ["foo/bar/MyClass.java"],
- unsafe_ignore_missing_latest_api: true,
- apex_available: ["myapex"],
- }
- `
- // In this test the source (java_library) libfoo is active since the
- // prebuilt (java_import) defaults to prefer:false. However the
- // prebuilt_apex module always depends on the prebuilt, and so it doesn't
- // find the dex boot jar in it. We either need to disable the source libfoo
- // or make the prebuilt libfoo preferred.
- testDexpreoptWithApexes(t, bp, "module libfoo does not provide a dex boot jar", preparer, fragment)
- // dexbootjar check is skipped if AllowMissingDependencies is true
- preparerAllowMissingDeps := android.GroupFixturePreparers(
- preparer,
- android.PrepareForTestWithAllowMissingDependencies,
- )
- testDexpreoptWithApexes(t, bp, "", preparerAllowMissingDeps, fragment)
- })
- t.Run("prebuilt library preferred with source", func(t *testing.T) {
- bp := `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- contents: ["libfoo", "libbar"],
- apex_available: ["myapex"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
- filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
- filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
- },
- }
- java_import {
- name: "libfoo",
- prefer: true,
- jars: ["libfoo.jar"],
- apex_available: ["myapex"],
- permitted_packages: ["foo"],
- }
- java_library {
- name: "libfoo",
- srcs: ["foo/bar/MyClass.java"],
- apex_available: ["myapex"],
- }
- java_sdk_library_import {
- name: "libbar",
- prefer: true,
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["myapex"],
- shared_library: false,
- permitted_packages: ["bar"],
- }
- java_sdk_library {
- name: "libbar",
- srcs: ["foo/bar/MyClass.java"],
- unsafe_ignore_missing_latest_api: true,
- apex_available: ["myapex"],
- }
- `
- ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
- checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
- my-bootclasspath-fragment/index.csv
- out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- `)
- })
- t.Run("prebuilt with source apex preferred", func(t *testing.T) {
- bp := `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["libfoo", "libbar"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- contents: ["libfoo", "libbar"],
- apex_available: ["myapex"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
- filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
- filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
- },
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: ["myapex"],
- }
- java_library {
- name: "libfoo",
- srcs: ["foo/bar/MyClass.java"],
- apex_available: ["myapex"],
- permitted_packages: ["foo"],
- }
- java_sdk_library_import {
- name: "libbar",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["myapex"],
- shared_library: false,
- }
- java_sdk_library {
- name: "libbar",
- srcs: ["foo/bar/MyClass.java"],
- unsafe_ignore_missing_latest_api: true,
- apex_available: ["myapex"],
- permitted_packages: ["bar"],
- }
- `
- ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
- // Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
- checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
- my-bootclasspath-fragment/index.csv
- out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- `)
- })
- t.Run("prebuilt preferred with source apex disabled", func(t *testing.T) {
- bp := `
- apex {
- name: "myapex",
- enabled: false,
- key: "myapex.key",
- java_libs: ["libfoo", "libbar"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- contents: ["libfoo", "libbar"],
- apex_available: ["myapex"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
- filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
- filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
- },
- }
- java_import {
- name: "libfoo",
- prefer: true,
- jars: ["libfoo.jar"],
- apex_available: ["myapex"],
- permitted_packages: ["foo"],
- }
- java_library {
- name: "libfoo",
- srcs: ["foo/bar/MyClass.java"],
- apex_available: ["myapex"],
- }
- java_sdk_library_import {
- name: "libbar",
- prefer: true,
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["myapex"],
- shared_library: false,
- permitted_packages: ["bar"],
- }
- java_sdk_library {
- name: "libbar",
- srcs: ["foo/bar/MyClass.java"],
- unsafe_ignore_missing_latest_api: true,
- apex_available: ["myapex"],
- }
- `
- ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
- checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
- // Verify the correct module jars contribute to the hiddenapi index file.
- checkHiddenAPIIndexFromClassesInputs(t, ctx, ``)
- checkHiddenAPIIndexFromFlagsInputs(t, ctx, `
- my-bootclasspath-fragment/index.csv
- out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv
- `)
- })
- }
- func TestApexWithTests(t *testing.T) {
- ctx := testApex(t, `
- apex_test {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- tests: [
- "mytest",
- "mytests",
- ],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- filegroup {
- name: "fg",
- srcs: [
- "baz",
- "bar/baz"
- ],
- }
- cc_test {
- name: "mytest",
- gtest: false,
- srcs: ["mytest.cpp"],
- relative_install_path: "test",
- shared_libs: ["mylib"],
- system_shared_libs: [],
- static_executable: true,
- stl: "none",
- data: [":fg"],
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- }
- filegroup {
- name: "fg2",
- srcs: [
- "testdata/baz"
- ],
- }
- cc_test {
- name: "mytests",
- gtest: false,
- srcs: [
- "mytest1.cpp",
- "mytest2.cpp",
- "mytest3.cpp",
- ],
- test_per_src: true,
- relative_install_path: "test",
- system_shared_libs: [],
- static_executable: true,
- stl: "none",
- data: [
- ":fg",
- ":fg2",
- ],
- }
- `)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- // Ensure that test dep (and their transitive dependencies) are copied into apex.
- ensureContains(t, copyCmds, "image.apex/bin/test/mytest")
- ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
- //Ensure that test data are copied into apex.
- ensureContains(t, copyCmds, "image.apex/bin/test/baz")
- ensureContains(t, copyCmds, "image.apex/bin/test/bar/baz")
- // Ensure that test deps built with `test_per_src` are copied into apex.
- ensureContains(t, copyCmds, "image.apex/bin/test/mytest1")
- ensureContains(t, copyCmds, "image.apex/bin/test/mytest2")
- ensureContains(t, copyCmds, "image.apex/bin/test/mytest3")
- // Ensure the module is correctly translated.
- bundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, bundle)
- name := bundle.BaseModuleName()
- prefix := "TARGET_"
- var builder strings.Builder
- data.Custom(&builder, name, prefix, "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")
- flatBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
- data = android.AndroidMkDataForTest(t, ctx, flatBundle)
- data.Custom(&builder, name, prefix, "", data)
- flatAndroidMk := builder.String()
- ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :baz :bar/baz\n")
- ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :testdata/baz\n")
- }
- func TestInstallExtraFlattenedApexes(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.InstallExtraFlattenedApexes = proptools.BoolPtr(true)
- }),
- )
- ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- ensureListContains(t, ab.requiredDeps, "myapex.flattened")
- mk := android.AndroidMkDataForTest(t, ctx, ab)
- var builder strings.Builder
- mk.Custom(&builder, ab.Name(), "TARGET_", "", mk)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += myapex.flattened")
- }
- func TestErrorsIfDepsAreNotEnabled(t *testing.T) {
- testApexError(t, `module "myapex" .* depends on disabled module "libfoo"`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- stl: "none",
- system_shared_libs: [],
- enabled: false,
- apex_available: ["myapex"],
- }
- `)
- testApexError(t, `module "myapex" .* depends on disabled module "myjar"`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["myjar"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- enabled: false,
- apex_available: ["myapex"],
- }
- `)
- }
- func TestApexWithJavaImport(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["myjavaimport"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_import {
- name: "myjavaimport",
- apex_available: ["myapex"],
- jars: ["my.jar"],
- compile_dex: true,
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule := module.Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/javalib/myjavaimport.jar")
- }
- func TestApexWithApps(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: [
- "AppFoo",
- "AppFooPriv",
- ],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app {
- name: "AppFoo",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "current",
- system_modules: "none",
- jni_libs: ["libjni"],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- android_app {
- name: "AppFooPriv",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "current",
- system_modules: "none",
- privileged: true,
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library_shared {
- name: "libjni",
- srcs: ["mylib.cpp"],
- shared_libs: ["libfoo"],
- stl: "none",
- system_shared_libs: [],
- apex_available: [ "myapex" ],
- sdk_version: "current",
- }
- cc_library_shared {
- name: "libfoo",
- stl: "none",
- system_shared_libs: [],
- apex_available: [ "myapex" ],
- sdk_version: "current",
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule := module.Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
- ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk")
- appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs")
- // JNI libraries are uncompressed
- if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") {
- t.Errorf("jni libs are not uncompressed for AppFoo")
- }
- // JNI libraries including transitive deps are
- for _, jni := range []string{"libjni", "libfoo"} {
- jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile().RelativeToTop()
- // ... embedded inside APK (jnilibs.zip)
- ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
- // ... and not directly inside the APEX
- ensureNotContains(t, copyCmds, "image.apex/lib64/"+jni+".so")
- }
- }
- func TestApexWithAppImports(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: [
- "AppFooPrebuilt",
- "AppFooPrivPrebuilt",
- ],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app_import {
- name: "AppFooPrebuilt",
- apk: "PrebuiltAppFoo.apk",
- presigned: true,
- dex_preopt: {
- enabled: false,
- },
- apex_available: ["myapex"],
- }
- android_app_import {
- name: "AppFooPrivPrebuilt",
- apk: "PrebuiltAppFooPriv.apk",
- privileged: true,
- presigned: true,
- dex_preopt: {
- enabled: false,
- },
- filename: "AwesomePrebuiltAppFooPriv.apk",
- apex_available: ["myapex"],
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule := module.Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt/AppFooPrebuilt.apk")
- ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AwesomePrebuiltAppFooPriv.apk")
- }
- func TestApexWithAppImportsPrefer(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: [
- "AppFoo",
- ],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app {
- name: "AppFoo",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- apex_available: [ "myapex" ],
- }
- android_app_import {
- name: "AppFoo",
- apk: "AppFooPrebuilt.apk",
- filename: "AppFooPrebuilt.apk",
- presigned: true,
- prefer: true,
- apex_available: ["myapex"],
- }
- `, withFiles(map[string][]byte{
- "AppFooPrebuilt.apk": nil,
- }))
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "app/AppFoo/AppFooPrebuilt.apk",
- })
- }
- func TestApexWithTestHelperApp(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: [
- "TesterHelpAppFoo",
- ],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_test_helper_app {
- name: "TesterHelpAppFoo",
- srcs: ["foo/bar/MyClass.java"],
- apex_available: [ "myapex" ],
- }
- `)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- apexRule := module.Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo/TesterHelpAppFoo.apk")
- }
- func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
- // libfoo's apex_available comes from cc_defaults
- testApexError(t, `requires "libfoo" that doesn't list the APEX under 'apex_available'.`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- apex {
- name: "otherapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- updatable: false,
- }
- cc_defaults {
- name: "libfoo-defaults",
- apex_available: ["otherapex"],
- }
- cc_library {
- name: "libfoo",
- defaults: ["libfoo-defaults"],
- stl: "none",
- system_shared_libs: [],
- }`)
- }
- func TestApexAvailable_DirectDep(t *testing.T) {
- // libfoo is not available to myapex, but only to otherapex
- testApexError(t, "requires \"libfoo\" that doesn't list the APEX under 'apex_available'.", `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- apex {
- name: "otherapex",
- key: "otherapex.key",
- native_shared_libs: ["libfoo"],
- updatable: false,
- }
- apex_key {
- name: "otherapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- stl: "none",
- system_shared_libs: [],
- apex_available: ["otherapex"],
- }`)
- }
- func TestApexAvailable_IndirectDep(t *testing.T) {
- // libbbaz is an indirect dep
- testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.\n\nDependency path:
- .*via tag apex\.dependencyTag.*name:sharedLib.*
- .*-> libfoo.*link:shared.*
- .*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.*
- .*-> libbar.*link:shared.*
- .*via tag cc\.libraryDependencyTag.*Kind:sharedLibraryDependency.*
- .*-> libbaz.*link:shared.*`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- stl: "none",
- shared_libs: ["libbar"],
- system_shared_libs: [],
- apex_available: ["myapex"],
- }
- cc_library {
- name: "libbar",
- stl: "none",
- shared_libs: ["libbaz"],
- system_shared_libs: [],
- apex_available: ["myapex"],
- }
- cc_library {
- name: "libbaz",
- stl: "none",
- system_shared_libs: [],
- }`)
- }
- func TestApexAvailable_InvalidApexName(t *testing.T) {
- testApexError(t, "\"otherapex\" is not a valid module name", `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- stl: "none",
- system_shared_libs: [],
- apex_available: ["otherapex"],
- }`)
- testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo", "libbar"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- stl: "none",
- system_shared_libs: [],
- runtime_libs: ["libbaz"],
- apex_available: ["myapex"],
- }
- cc_library {
- name: "libbar",
- stl: "none",
- system_shared_libs: [],
- apex_available: ["//apex_available:anyapex"],
- }
- cc_library {
- name: "libbaz",
- stl: "none",
- system_shared_libs: [],
- stubs: {
- versions: ["10", "20", "30"],
- },
- }`)
- }
- func TestApexAvailable_CheckForPlatform(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libbar", "libbaz"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- stl: "none",
- system_shared_libs: [],
- shared_libs: ["libbar"],
- apex_available: ["//apex_available:platform"],
- }
- cc_library {
- name: "libfoo2",
- stl: "none",
- system_shared_libs: [],
- shared_libs: ["libbaz"],
- apex_available: ["//apex_available:platform"],
- }
- cc_library {
- name: "libbar",
- stl: "none",
- system_shared_libs: [],
- apex_available: ["myapex"],
- }
- cc_library {
- name: "libbaz",
- stl: "none",
- system_shared_libs: [],
- apex_available: ["myapex"],
- stubs: {
- versions: ["1"],
- },
- }`)
- // libfoo shouldn't be available to platform even though it has "//apex_available:platform",
- // because it depends on libbar which isn't available to platform
- libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
- if libfoo.NotAvailableForPlatform() != true {
- t.Errorf("%q shouldn't be available to platform", libfoo.String())
- }
- // libfoo2 however can be available to platform because it depends on libbaz which provides
- // stubs
- libfoo2 := ctx.ModuleForTests("libfoo2", "android_arm64_armv8-a_shared").Module().(*cc.Module)
- if libfoo2.NotAvailableForPlatform() == true {
- t.Errorf("%q should be available to platform", libfoo2.String())
- }
- }
- func TestApexAvailable_CreatedForApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["libfoo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "libfoo",
- stl: "none",
- system_shared_libs: [],
- apex_available: ["myapex"],
- static: {
- apex_available: ["//apex_available:platform"],
- },
- }`)
- libfooShared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*cc.Module)
- if libfooShared.NotAvailableForPlatform() != true {
- t.Errorf("%q shouldn't be available to platform", libfooShared.String())
- }
- libfooStatic := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*cc.Module)
- if libfooStatic.NotAvailableForPlatform() != false {
- t.Errorf("%q should be available to platform", libfooStatic.String())
- }
- }
- func TestOverrideApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: ["app"],
- bpfs: ["bpf"],
- prebuilts: ["myetc"],
- overrides: ["oldapex"],
- updatable: false,
- }
- override_apex {
- name: "override_myapex",
- base: "myapex",
- apps: ["override_app"],
- bpfs: ["override_bpf"],
- prebuilts: ["override_myetc"],
- overrides: ["unknownapex"],
- logging_parent: "com.foo.bar",
- package_name: "test.overridden.package",
- key: "mynewapex.key",
- certificate: ":myapex.certificate",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- apex_key {
- name: "mynewapex.key",
- public_key: "testkey2.avbpubkey",
- private_key: "testkey2.pem",
- }
- android_app_certificate {
- name: "myapex.certificate",
- certificate: "testkey",
- }
- android_app {
- name: "app",
- srcs: ["foo/bar/MyClass.java"],
- package_name: "foo",
- sdk_version: "none",
- system_modules: "none",
- apex_available: [ "myapex" ],
- }
- override_android_app {
- name: "override_app",
- base: "app",
- package_name: "bar",
- }
- bpf {
- name: "bpf",
- srcs: ["bpf.c"],
- }
- bpf {
- name: "override_bpf",
- srcs: ["override_bpf.c"],
- }
- prebuilt_etc {
- name: "myetc",
- src: "myprebuilt",
- }
- prebuilt_etc {
- name: "override_myetc",
- src: "override_myprebuilt",
- }
- `, withManifestPackageNameOverrides([]string{"myapex:com.android.myapex"}))
- originalVariant := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(android.OverridableModule)
- overriddenVariant := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image").Module().(android.OverridableModule)
- if originalVariant.GetOverriddenBy() != "" {
- t.Errorf("GetOverriddenBy should be empty, but was %q", originalVariant.GetOverriddenBy())
- }
- if overriddenVariant.GetOverriddenBy() != "override_myapex" {
- t.Errorf("GetOverriddenBy should be \"override_myapex\", but was %q", overriddenVariant.GetOverriddenBy())
- }
- module := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image")
- apexRule := module.Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
- ensureNotContains(t, copyCmds, "image.apex/app/app/app.apk")
- ensureContains(t, copyCmds, "image.apex/app/override_app/override_app.apk")
- ensureNotContains(t, copyCmds, "image.apex/etc/bpf/bpf.o")
- ensureContains(t, copyCmds, "image.apex/etc/bpf/override_bpf.o")
- ensureNotContains(t, copyCmds, "image.apex/etc/myetc")
- ensureContains(t, copyCmds, "image.apex/etc/override_myetc")
- apexBundle := module.Module().(*apexBundle)
- name := apexBundle.Name()
- if name != "override_myapex" {
- t.Errorf("name should be \"override_myapex\", but was %q", name)
- }
- if apexBundle.overridableProperties.Logging_parent != "com.foo.bar" {
- t.Errorf("override_myapex should have logging parent (com.foo.bar), but was %q.", apexBundle.overridableProperties.Logging_parent)
- }
- optFlags := apexRule.Args["opt_flags"]
- ensureContains(t, optFlags, "--override_apk_package_name test.overridden.package")
- ensureContains(t, optFlags, "--pubkey testkey2.avbpubkey")
- signApkRule := module.Rule("signapk")
- ensureEquals(t, signApkRule.Args["certificates"], "testkey.x509.pem testkey.pk8")
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- var builder strings.Builder
- data.Custom(&builder, name, "TARGET_", "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex")
- ensureContains(t, androidMk, "LOCAL_MODULE := override_bpf.o.override_myapex")
- ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex")
- ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex")
- ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := bpf.myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := override_app.myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex")
- ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex")
- }
- func TestLegacyAndroid10Support(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- stl: "libc++",
- system_shared_libs: [],
- apex_available: [ "myapex" ],
- min_sdk_version: "29",
- }
- `, withUnbundledBuild)
- module := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- args := module.Rule("apexRule").Args
- ensureContains(t, args["opt_flags"], "--manifest_json "+module.Output("apex_manifest.json").Output.String())
- ensureNotContains(t, args["opt_flags"], "--no_hashtree")
- // The copies of the libraries in the apex should have one more dependency than
- // the ones outside the apex, namely the unwinder. Ideally we should check
- // the dependency names directly here but for some reason the names are blank in
- // this test.
- for _, lib := range []string{"libc++", "mylib"} {
- apexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared_apex29").Rule("ld").Implicits
- nonApexImplicits := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld").Implicits
- if len(apexImplicits) != len(nonApexImplicits)+1 {
- t.Errorf("%q missing unwinder dep", lib)
- }
- }
- }
- var filesForSdkLibrary = android.MockFS{
- "api/current.txt": nil,
- "api/removed.txt": nil,
- "api/system-current.txt": nil,
- "api/system-removed.txt": nil,
- "api/test-current.txt": nil,
- "api/test-removed.txt": nil,
- "100/public/api/foo.txt": nil,
- "100/public/api/foo-removed.txt": nil,
- "100/system/api/foo.txt": nil,
- "100/system/api/foo-removed.txt": nil,
- // For java_sdk_library_import
- "a.jar": nil,
- }
- func TestJavaSDKLibrary(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["foo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_sdk_library {
- name: "foo",
- srcs: ["a.java"],
- api_packages: ["foo"],
- apex_available: [ "myapex" ],
- }
- prebuilt_apis {
- name: "sdk",
- api_dirs: ["100"],
- }
- `, withFiles(filesForSdkLibrary))
- // java_sdk_library installs both impl jar and permission XML
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "javalib/foo.jar",
- "etc/permissions/foo.xml",
- })
- // Permission XML should point to the activated path of impl jar of java_sdk_library
- sdkLibrary := ctx.ModuleForTests("foo.xml", "android_common_myapex").Rule("java_sdk_xml")
- ensureMatches(t, sdkLibrary.RuleParams.Command, `<library\\n\s+name=\\\"foo\\\"\\n\s+file=\\\"/apex/myapex/javalib/foo.jar\\\"`)
- }
- func TestJavaSDKLibrary_WithinApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["foo", "bar"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_sdk_library {
- name: "foo",
- srcs: ["a.java"],
- api_packages: ["foo"],
- apex_available: ["myapex"],
- sdk_version: "none",
- system_modules: "none",
- }
- java_library {
- name: "bar",
- srcs: ["a.java"],
- libs: ["foo"],
- apex_available: ["myapex"],
- sdk_version: "none",
- system_modules: "none",
- }
- prebuilt_apis {
- name: "sdk",
- api_dirs: ["100"],
- }
- `, withFiles(filesForSdkLibrary))
- // java_sdk_library installs both impl jar and permission XML
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "javalib/bar.jar",
- "javalib/foo.jar",
- "etc/permissions/foo.xml",
- })
- // The bar library should depend on the implementation jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
- if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
- t.Errorf("expected %q, found %#q", expected, actual)
- }
- }
- func TestJavaSDKLibrary_CrossBoundary(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["foo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_sdk_library {
- name: "foo",
- srcs: ["a.java"],
- api_packages: ["foo"],
- apex_available: ["myapex"],
- sdk_version: "none",
- system_modules: "none",
- }
- java_library {
- name: "bar",
- srcs: ["a.java"],
- libs: ["foo"],
- sdk_version: "none",
- system_modules: "none",
- }
- prebuilt_apis {
- name: "sdk",
- api_dirs: ["100"],
- }
- `, withFiles(filesForSdkLibrary))
- // java_sdk_library installs both impl jar and permission XML
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "javalib/foo.jar",
- "etc/permissions/foo.xml",
- })
- // The bar library should depend on the stubs jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common").Rule("javac")
- if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.stubs\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
- t.Errorf("expected %q, found %#q", expected, actual)
- }
- }
- func TestJavaSDKLibrary_ImportPreferred(t *testing.T) {
- ctx := testApex(t, `
- prebuilt_apis {
- name: "sdk",
- api_dirs: ["100"],
- }`,
- withFiles(map[string][]byte{
- "apex/a.java": nil,
- "apex/apex_manifest.json": nil,
- "apex/Android.bp": []byte(`
- package {
- default_visibility: ["//visibility:private"],
- }
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["foo", "bar"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "bar",
- srcs: ["a.java"],
- libs: ["foo"],
- apex_available: ["myapex"],
- sdk_version: "none",
- system_modules: "none",
- }
- `),
- "source/a.java": nil,
- "source/api/current.txt": nil,
- "source/api/removed.txt": nil,
- "source/Android.bp": []byte(`
- package {
- default_visibility: ["//visibility:private"],
- }
- java_sdk_library {
- name: "foo",
- visibility: ["//apex"],
- srcs: ["a.java"],
- api_packages: ["foo"],
- apex_available: ["myapex"],
- sdk_version: "none",
- system_modules: "none",
- public: {
- enabled: true,
- },
- }
- `),
- "prebuilt/a.jar": nil,
- "prebuilt/Android.bp": []byte(`
- package {
- default_visibility: ["//visibility:private"],
- }
- java_sdk_library_import {
- name: "foo",
- visibility: ["//apex", "//source"],
- apex_available: ["myapex"],
- prefer: true,
- public: {
- jars: ["a.jar"],
- },
- }
- `),
- }), withFiles(filesForSdkLibrary),
- )
- // java_sdk_library installs both impl jar and permission XML
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "javalib/bar.jar",
- "javalib/foo.jar",
- "etc/permissions/foo.xml",
- })
- // The bar library should depend on the implementation jar.
- barLibrary := ctx.ModuleForTests("bar", "android_common_myapex").Rule("javac")
- if expected, actual := `^-classpath [^:]*/turbine-combined/foo\.impl\.jar$`, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
- t.Errorf("expected %q, found %#q", expected, actual)
- }
- }
- func TestJavaSDKLibrary_ImportOnly(t *testing.T) {
- testApexError(t, `java_libs: "foo" is not configured to be compiled into dex`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["foo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_sdk_library_import {
- name: "foo",
- apex_available: ["myapex"],
- prefer: true,
- public: {
- jars: ["a.jar"],
- },
- }
- `, withFiles(filesForSdkLibrary))
- }
- func TestCompatConfig(t *testing.T) {
- result := android.GroupFixturePreparers(
- prepareForApexTest,
- java.PrepareForTestWithPlatformCompatConfig,
- ).RunTestWithBp(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- compat_configs: ["myjar-platform-compat-config"],
- java_libs: ["myjar"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- platform_compat_config {
- name: "myjar-platform-compat-config",
- src: ":myjar",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- apex_available: [ "myapex" ],
- }
- // Make sure that a preferred prebuilt does not affect the apex contents.
- prebuilt_platform_compat_config {
- name: "myjar-platform-compat-config",
- metadata: "compat-config/metadata.xml",
- prefer: true,
- }
- `)
- ctx := result.TestContext
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "etc/compatconfig/myjar-platform-compat-config.xml",
- "javalib/myjar.jar",
- })
- }
- func TestRejectNonInstallableJavaLibrary(t *testing.T) {
- testApexError(t, `"myjar" is not configured to be compiled into dex`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["myjar"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- compile_dex: false,
- apex_available: ["myapex"],
- }
- `)
- }
- func TestCarryRequiredModuleNames(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- required: ["a", "b"],
- host_required: ["c", "d"],
- target_required: ["e", "f"],
- apex_available: [ "myapex" ],
- }
- `)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- name := apexBundle.BaseModuleName()
- prefix := "TARGET_"
- var builder strings.Builder
- data.Custom(&builder, name, prefix, "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += a b\n")
- ensureContains(t, androidMk, "LOCAL_HOST_REQUIRED_MODULES += c d\n")
- ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES += e f\n")
- }
- func TestSymlinksFromApexToSystem(t *testing.T) {
- bp := `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- java_libs: ["myjar"],
- updatable: false,
- }
- apex {
- name: "myapex.updatable",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- java_libs: ["myjar"],
- updatable: true,
- min_sdk_version: "current",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["myotherlib"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- "myapex.updatable",
- "//apex_available:platform",
- ],
- min_sdk_version: "current",
- }
- cc_library {
- name: "myotherlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- "myapex.updatable",
- "//apex_available:platform",
- ],
- min_sdk_version: "current",
- }
- java_library {
- name: "myjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- libs: ["myotherjar"],
- apex_available: [
- "myapex",
- "myapex.updatable",
- "//apex_available:platform",
- ],
- min_sdk_version: "current",
- }
- java_library {
- name: "myotherjar",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- apex_available: [
- "myapex",
- "myapex.updatable",
- "//apex_available:platform",
- ],
- min_sdk_version: "current",
- }
- `
- ensureRealfileExists := func(t *testing.T, files []fileInApex, file string) {
- for _, f := range files {
- if f.path == file {
- if f.isLink {
- t.Errorf("%q is not a real file", file)
- }
- return
- }
- }
- t.Errorf("%q is not found", file)
- }
- ensureSymlinkExists := func(t *testing.T, files []fileInApex, file string) {
- for _, f := range files {
- if f.path == file {
- if !f.isLink {
- t.Errorf("%q is not a symlink", file)
- }
- return
- }
- }
- t.Errorf("%q is not found", file)
- }
- // For unbundled build, symlink shouldn't exist regardless of whether an APEX
- // is updatable or not
- ctx := testApex(t, bp, withUnbundledBuild)
- files := getFiles(t, ctx, "myapex", "android_common_myapex_image")
- ensureRealfileExists(t, files, "javalib/myjar.jar")
- ensureRealfileExists(t, files, "lib64/mylib.so")
- ensureRealfileExists(t, files, "lib64/myotherlib.so")
- files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
- ensureRealfileExists(t, files, "javalib/myjar.jar")
- ensureRealfileExists(t, files, "lib64/mylib.so")
- ensureRealfileExists(t, files, "lib64/myotherlib.so")
- // For bundled build, symlink to the system for the non-updatable APEXes only
- ctx = testApex(t, bp)
- files = getFiles(t, ctx, "myapex", "android_common_myapex_image")
- ensureRealfileExists(t, files, "javalib/myjar.jar")
- ensureRealfileExists(t, files, "lib64/mylib.so")
- ensureSymlinkExists(t, files, "lib64/myotherlib.so") // this is symlink
- files = getFiles(t, ctx, "myapex.updatable", "android_common_myapex.updatable_image")
- ensureRealfileExists(t, files, "javalib/myjar.jar")
- ensureRealfileExists(t, files, "lib64/mylib.so")
- ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
- }
- func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library_shared {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["myotherlib"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- "//apex_available:platform",
- ],
- }
- cc_prebuilt_library_shared {
- name: "myotherlib",
- srcs: ["prebuilt.so"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [
- "myapex",
- "//apex_available:platform",
- ],
- }
- `)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- var builder strings.Builder
- data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
- androidMk := builder.String()
- // `myotherlib` is added to `myapex` as symlink
- ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n")
- ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n")
- // `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib`
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += mylib.myapex:64 myotherlib:64 apex_manifest.pb.myapex apex_pubkey.myapex\n")
- }
- func TestApexWithJniLibs(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- jni_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- shared_libs: ["mylib2"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- `)
- rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
- // Notice mylib2.so (transitive dep) is not added as a jni_lib
- ensureEquals(t, rule.Args["opt"], "-a jniLibs mylib.so")
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "lib64/mylib.so",
- "lib64/mylib2.so",
- })
- }
- func TestApexMutatorsDontRunIfDisabled(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `,
- android.FixtureModifyConfig(func(config android.Config) {
- delete(config.Targets, android.Android)
- config.AndroidCommonTarget = android.Target{}
- }),
- )
- if expected, got := []string{""}, ctx.ModuleVariantsForTests("myapex"); !reflect.DeepEqual(expected, got) {
- t.Errorf("Expected variants: %v, but got: %v", expected, got)
- }
- }
- func TestAppBundle(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: ["AppFoo"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app {
- name: "AppFoo",
- srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
- system_modules: "none",
- apex_available: [ "myapex" ],
- }
- `, withManifestPackageNameOverrides([]string{"AppFoo:com.android.foo"}))
- bundleConfigRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("bundle_config.json")
- content := bundleConfigRule.Args["content"]
- ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
- ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`)
- }
- func TestAppSetBundle(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: ["AppSet"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app_set {
- name: "AppSet",
- set: "AppSet.apks",
- }`)
- mod := ctx.ModuleForTests("myapex", "android_common_myapex_image")
- bundleConfigRule := mod.Output("bundle_config.json")
- content := bundleConfigRule.Args["content"]
- ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
- s := mod.Rule("apexRule").Args["copy_commands"]
- copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 3 {
- t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
- }
- ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet$")
- ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet$")
- ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$")
- }
- func TestAppSetBundlePrebuilt(t *testing.T) {
- bp := `
- apex_set {
- name: "myapex",
- filename: "foo_v2.apex",
- sanitized: {
- none: { set: "myapex.apks", },
- hwaddress: { set: "myapex.hwasan.apks", },
- },
- }
- `
- ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress)
- // Check that the extractor produces the correct output file from the correct input file.
- extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks"
- m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
- extractedApex := m.Output(extractorOutput)
- android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings())
- // Ditto for the apex.
- m = ctx.ModuleForTests("myapex", "android_common_myapex")
- copiedApex := m.Output("out/soong/.intermediates/myapex/android_common_myapex/foo_v2.apex")
- android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String())
- }
- func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer android.FixturePreparer, fragments ...java.ApexVariantReference) {
- t.Helper()
- bp := `
- java_library {
- name: "some-updatable-apex-lib",
- srcs: ["a.java"],
- sdk_version: "current",
- apex_available: [
- "some-updatable-apex",
- ],
- permitted_packages: ["some.updatable.apex.lib"],
- }
- java_library {
- name: "some-non-updatable-apex-lib",
- srcs: ["a.java"],
- apex_available: [
- "some-non-updatable-apex",
- ],
- compile_dex: true,
- permitted_packages: ["some.non.updatable.apex.lib"],
- }
- bootclasspath_fragment {
- name: "some-non-updatable-fragment",
- contents: ["some-non-updatable-apex-lib"],
- apex_available: [
- "some-non-updatable-apex",
- ],
- }
- java_library {
- name: "some-platform-lib",
- srcs: ["a.java"],
- sdk_version: "current",
- installable: true,
- }
- java_library {
- name: "some-art-lib",
- srcs: ["a.java"],
- sdk_version: "current",
- apex_available: [
- "com.android.art.debug",
- ],
- hostdex: true,
- compile_dex: true,
- }
- apex {
- name: "some-updatable-apex",
- key: "some-updatable-apex.key",
- java_libs: ["some-updatable-apex-lib"],
- updatable: true,
- min_sdk_version: "current",
- }
- apex {
- name: "some-non-updatable-apex",
- key: "some-non-updatable-apex.key",
- bootclasspath_fragments: ["some-non-updatable-fragment"],
- updatable: false,
- }
- apex_key {
- name: "some-updatable-apex.key",
- }
- apex_key {
- name: "some-non-updatable-apex.key",
- }
- apex {
- name: "com.android.art.debug",
- key: "com.android.art.debug.key",
- bootclasspath_fragments: ["art-bootclasspath-fragment"],
- updatable: true,
- min_sdk_version: "current",
- }
- bootclasspath_fragment {
- name: "art-bootclasspath-fragment",
- image_name: "art",
- contents: ["some-art-lib"],
- apex_available: [
- "com.android.art.debug",
- ],
- }
- apex_key {
- name: "com.android.art.debug.key",
- }
- filegroup {
- name: "some-updatable-apex-file_contexts",
- srcs: [
- "system/sepolicy/apex/some-updatable-apex-file_contexts",
- ],
- }
- filegroup {
- name: "some-non-updatable-apex-file_contexts",
- srcs: [
- "system/sepolicy/apex/some-non-updatable-apex-file_contexts",
- ],
- }
- `
- testDexpreoptWithApexes(t, bp, errmsg, preparer, fragments...)
- }
- func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.FixturePreparer, fragments ...java.ApexVariantReference) *android.TestContext {
- t.Helper()
- fs := android.MockFS{
- "a.java": nil,
- "a.jar": nil,
- "apex_manifest.json": nil,
- "AndroidManifest.xml": nil,
- "system/sepolicy/apex/myapex-file_contexts": nil,
- "system/sepolicy/apex/some-updatable-apex-file_contexts": nil,
- "system/sepolicy/apex/some-non-updatable-apex-file_contexts": nil,
- "system/sepolicy/apex/com.android.art.debug-file_contexts": nil,
- "framework/aidl/a.aidl": nil,
- }
- errorHandler := android.FixtureExpectsNoErrors
- if errmsg != "" {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg)
- }
- result := android.GroupFixturePreparers(
- cc.PrepareForTestWithCcDefaultModules,
- java.PrepareForTestWithHiddenApiBuildComponents,
- java.PrepareForTestWithJavaDefaultModules,
- java.PrepareForTestWithJavaSdkLibraryFiles,
- PrepareForTestWithApexBuildComponents,
- preparer,
- fs.AddToFixture(),
- android.FixtureModifyMockFS(func(fs android.MockFS) {
- if _, ok := fs["frameworks/base/boot/Android.bp"]; !ok {
- insert := ""
- for _, fragment := range fragments {
- insert += fmt.Sprintf("{apex: %q, module: %q},\n", *fragment.Apex, *fragment.Module)
- }
- fs["frameworks/base/boot/Android.bp"] = []byte(fmt.Sprintf(`
- platform_bootclasspath {
- name: "platform-bootclasspath",
- fragments: [
- %s
- ],
- }
- `, insert))
- }
- }),
- dexpreopt.FixtureSetBootImageProfiles("art/build/boot/boot-image-profile.txt"),
- ).
- ExtendWithErrorHandler(errorHandler).
- RunTestWithBp(t, bp)
- return result.TestContext
- }
- func TestDuplicateDeapexeresFromPrebuiltApexes(t *testing.T) {
- preparers := android.GroupFixturePreparers(
- java.PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithApexBuildComponents,
- ).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
- "Multiple installable prebuilt APEXes provide ambiguous deapexers: com.android.myapex and com.mycompany.android.myapex"))
- bpBase := `
- apex_set {
- name: "com.android.myapex",
- installable: true,
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- set: "myapex.apks",
- }
- apex_set {
- name: "com.mycompany.android.myapex",
- apex_name: "com.android.myapex",
- installable: true,
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- set: "company-myapex.apks",
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- apex_available: ["com.android.myapex"],
- %s
- }
- `
- t.Run("java_import", func(t *testing.T) {
- _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: ["com.android.myapex"],
- }
- `)
- })
- t.Run("java_sdk_library_import", func(t *testing.T) {
- _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
- java_sdk_library_import {
- name: "libfoo",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["com.android.myapex"],
- }
- `)
- })
- t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) {
- _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `
- image_name: "art",
- contents: ["libfoo"],
- `)+`
- java_sdk_library_import {
- name: "libfoo",
- public: {
- jars: ["libbar.jar"],
- },
- apex_available: ["com.android.myapex"],
- }
- `)
- })
- }
- func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
- testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- }
- func TestUpdatableDefault_should_set_min_sdk_version(t *testing.T) {
- testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- }
- func TestUpdatable_cannot_be_vendor_apex(t *testing.T) {
- testApexError(t, `"myapex" .*: updatable: vendor APEXes are not updatable`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: true,
- soc_specific: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- }
- func TestUpdatable_should_not_set_generate_classpaths_proto(t *testing.T) {
- testApexError(t, `"mysystemserverclasspathfragment" .* it must not set generate_classpaths_proto to false`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- systemserverclasspath_fragments: [
- "mysystemserverclasspathfragment",
- ],
- min_sdk_version: "29",
- updatable: true,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "foo",
- srcs: ["b.java"],
- min_sdk_version: "29",
- installable: true,
- apex_available: [
- "myapex",
- ],
- }
- systemserverclasspath_fragment {
- name: "mysystemserverclasspathfragment",
- generate_classpaths_proto: false,
- contents: [
- "foo",
- ],
- apex_available: [
- "myapex",
- ],
- }
- `,
- dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
- )
- }
- func TestNoUpdatableJarsInBootImage(t *testing.T) {
- // Set the BootJars in dexpreopt.GlobalConfig and productVariables to the same value. This can
- // result in an invalid configuration as it does not set the ArtApexJars and allows art apex
- // modules to be included in the BootJars.
- prepareSetBootJars := func(bootJars ...string) android.FixturePreparer {
- return android.GroupFixturePreparers(
- dexpreopt.FixtureSetBootJars(bootJars...),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.BootJars = android.CreateTestConfiguredJarList(bootJars)
- }),
- )
- }
- // Set the ArtApexJars and BootJars in dexpreopt.GlobalConfig and productVariables all to the
- // same value. This can result in an invalid configuration as it allows non art apex jars to be
- // specified in the ArtApexJars configuration.
- prepareSetArtJars := func(bootJars ...string) android.FixturePreparer {
- return android.GroupFixturePreparers(
- dexpreopt.FixtureSetArtBootJars(bootJars...),
- dexpreopt.FixtureSetBootJars(bootJars...),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.BootJars = android.CreateTestConfiguredJarList(bootJars)
- }),
- )
- }
- t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) {
- preparer := android.GroupFixturePreparers(
- java.FixtureConfigureBootJars("com.android.art.debug:some-art-lib"),
- java.FixtureConfigureApexBootJars("some-non-updatable-apex:some-non-updatable-apex-lib"),
- )
- fragments := []java.ApexVariantReference{
- {
- Apex: proptools.StringPtr("com.android.art.debug"),
- Module: proptools.StringPtr("art-bootclasspath-fragment"),
- },
- {
- Apex: proptools.StringPtr("some-non-updatable-apex"),
- Module: proptools.StringPtr("some-non-updatable-fragment"),
- },
- }
- testNoUpdatableJarsInBootImage(t, "", preparer, fragments...)
- })
- t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
- err := `module "some-art-lib" from updatable apexes \["com.android.art.debug"\] is not allowed in the framework boot image`
- // Update the dexpreopt BootJars directly.
- preparer := android.GroupFixturePreparers(
- prepareSetBootJars("com.android.art.debug:some-art-lib"),
- java.FixtureConfigureApexBootJars("some-non-updatable-apex:some-non-updatable-apex-lib"),
- )
- testNoUpdatableJarsInBootImage(t, err, preparer)
- })
- t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- err := `ArtApexJars expects this to be in apex "some-updatable-apex" but this is only in apexes.*"com.android.art.debug"`
- // Update the dexpreopt ArtApexJars directly.
- preparer := prepareSetArtJars("some-updatable-apex:some-updatable-apex-lib")
- testNoUpdatableJarsInBootImage(t, err, preparer)
- })
- t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- err := `ArtApexJars expects this to be in apex "some-non-updatable-apex" but this is only in apexes.*"com.android.art.debug"`
- // Update the dexpreopt ArtApexJars directly.
- preparer := prepareSetArtJars("some-non-updatable-apex:some-non-updatable-apex-lib")
- testNoUpdatableJarsInBootImage(t, err, preparer)
- })
- t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
- err := `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the framework boot image`
- preparer := android.GroupFixturePreparers(
- java.FixtureConfigureBootJars("some-updatable-apex:some-updatable-apex-lib"),
- java.FixtureConfigureApexBootJars("some-non-updatable-apex:some-non-updatable-apex-lib"),
- )
- testNoUpdatableJarsInBootImage(t, err, preparer)
- })
- t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) {
- preparer := java.FixtureConfigureApexBootJars("some-non-updatable-apex:some-non-updatable-apex-lib")
- fragment := java.ApexVariantReference{
- Apex: proptools.StringPtr("some-non-updatable-apex"),
- Module: proptools.StringPtr("some-non-updatable-fragment"),
- }
- testNoUpdatableJarsInBootImage(t, "", preparer, fragment)
- })
- t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) {
- err := `"platform-bootclasspath" depends on undefined module "nonexistent"`
- preparer := java.FixtureConfigureBootJars("platform:nonexistent")
- testNoUpdatableJarsInBootImage(t, err, preparer)
- })
- t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) {
- err := `"platform-bootclasspath" depends on undefined module "nonexistent"`
- preparer := java.FixtureConfigureBootJars("platform:nonexistent")
- testNoUpdatableJarsInBootImage(t, err, preparer)
- })
- t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
- err := `ArtApexJars is invalid as it requests a platform variant of "some-platform-lib"`
- // Update the dexpreopt ArtApexJars directly.
- preparer := prepareSetArtJars("platform:some-platform-lib")
- testNoUpdatableJarsInBootImage(t, err, preparer)
- })
- t.Run("platform jar in the framework boot image => ok", func(t *testing.T) {
- preparer := android.GroupFixturePreparers(
- java.FixtureConfigureBootJars("platform:some-platform-lib"),
- java.FixtureConfigureApexBootJars("some-non-updatable-apex:some-non-updatable-apex-lib"),
- )
- fragments := []java.ApexVariantReference{
- {
- Apex: proptools.StringPtr("some-non-updatable-apex"),
- Module: proptools.StringPtr("some-non-updatable-fragment"),
- },
- }
- testNoUpdatableJarsInBootImage(t, "", preparer, fragments...)
- })
- }
- func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) {
- preparer := java.FixtureConfigureApexBootJars("myapex:libfoo")
- t.Run("prebuilt no source", func(t *testing.T) {
- fragment := java.ApexVariantReference{
- Apex: proptools.StringPtr("myapex"),
- Module: proptools.StringPtr("my-bootclasspath-fragment"),
- }
- testDexpreoptWithApexes(t, `
- prebuilt_apex {
- name: "myapex" ,
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
- }
- prebuilt_bootclasspath_fragment {
- name: "my-bootclasspath-fragment",
- contents: ["libfoo"],
- apex_available: ["myapex"],
- hidden_api: {
- annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
- metadata: "my-bootclasspath-fragment/metadata.csv",
- index: "my-bootclasspath-fragment/index.csv",
- signature_patterns: "my-bootclasspath-fragment/signature-patterns.csv",
- filtered_stub_flags: "my-bootclasspath-fragment/filtered-stub-flags.csv",
- filtered_flags: "my-bootclasspath-fragment/filtered-flags.csv",
- },
- }
- java_import {
- name: "libfoo",
- jars: ["libfoo.jar"],
- apex_available: ["myapex"],
- permitted_packages: ["libfoo"],
- }
- `, "", preparer, fragment)
- })
- }
- func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, bootJars []string, rules []android.Rule) {
- t.Helper()
- bp += `
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }`
- fs := android.MockFS{
- "lib1/src/A.java": nil,
- "lib2/src/B.java": nil,
- "system/sepolicy/apex/myapex-file_contexts": nil,
- }
- errorHandler := android.FixtureExpectsNoErrors
- if errmsg != "" {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg)
- }
- android.GroupFixturePreparers(
- android.PrepareForTestWithAndroidBuildComponents,
- java.PrepareForTestWithJavaBuildComponents,
- PrepareForTestWithApexBuildComponents,
- android.PrepareForTestWithNeverallowRules(rules),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- apexBootJars := make([]string, 0, len(bootJars))
- for _, apexBootJar := range bootJars {
- apexBootJars = append(apexBootJars, "myapex:"+apexBootJar)
- }
- variables.ApexBootJars = android.CreateTestConfiguredJarList(apexBootJars)
- }),
- fs.AddToFixture(),
- ).
- ExtendWithErrorHandler(errorHandler).
- RunTestWithBp(t, bp)
- }
- func TestApexPermittedPackagesRules(t *testing.T) {
- testcases := []struct {
- name string
- expectedError string
- bp string
- bootJars []string
- modulesPackages map[string][]string
- }{
- {
- name: "Non-Bootclasspath apex jar not satisfying allowed module packages.",
- expectedError: "",
- bp: `
- java_library {
- name: "bcp_lib1",
- srcs: ["lib1/src/*.java"],
- permitted_packages: ["foo.bar"],
- apex_available: ["myapex"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "30",
- }
- java_library {
- name: "nonbcp_lib2",
- srcs: ["lib2/src/*.java"],
- apex_available: ["myapex"],
- permitted_packages: ["a.b"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "30",
- }
- apex {
- name: "myapex",
- min_sdk_version: "30",
- key: "myapex.key",
- java_libs: ["bcp_lib1", "nonbcp_lib2"],
- updatable: false,
- }`,
- bootJars: []string{"bcp_lib1"},
- modulesPackages: map[string][]string{
- "myapex": []string{
- "foo.bar",
- },
- },
- },
- {
- name: "Bootclasspath apex jar not satisfying allowed module packages on Q.",
- expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`,
- bp: `
- java_library {
- name: "bcp_lib1",
- srcs: ["lib1/src/*.java"],
- apex_available: ["myapex"],
- permitted_packages: ["foo.bar"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "29",
- }
- java_library {
- name: "bcp_lib2",
- srcs: ["lib2/src/*.java"],
- apex_available: ["myapex"],
- permitted_packages: ["foo.bar", "bar.baz"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "29",
- }
- apex {
- name: "myapex",
- min_sdk_version: "29",
- key: "myapex.key",
- java_libs: ["bcp_lib1", "bcp_lib2"],
- updatable: false,
- }
- `,
- bootJars: []string{"bcp_lib1", "bcp_lib2"},
- modulesPackages: map[string][]string{
- "myapex": []string{
- "foo.bar",
- },
- },
- },
- {
- name: "Bootclasspath apex jar not satisfying allowed module packages on R.",
- expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`,
- bp: `
- java_library {
- name: "bcp_lib1",
- srcs: ["lib1/src/*.java"],
- apex_available: ["myapex"],
- permitted_packages: ["foo.bar"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "30",
- }
- java_library {
- name: "bcp_lib2",
- srcs: ["lib2/src/*.java"],
- apex_available: ["myapex"],
- permitted_packages: ["foo.bar", "bar.baz"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "30",
- }
- apex {
- name: "myapex",
- min_sdk_version: "30",
- key: "myapex.key",
- java_libs: ["bcp_lib1", "bcp_lib2"],
- updatable: false,
- }
- `,
- bootJars: []string{"bcp_lib1", "bcp_lib2"},
- modulesPackages: map[string][]string{
- "myapex": []string{
- "foo.bar",
- },
- },
- },
- {
- name: "Bootclasspath apex jar >= T not satisfying Q/R/S allowed module packages.",
- expectedError: "",
- bp: `
- java_library {
- name: "bcp_lib1",
- srcs: ["lib1/src/*.java"],
- apex_available: ["myapex"],
- permitted_packages: ["foo.bar"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "current",
- }
- java_library {
- name: "bcp_lib2",
- srcs: ["lib2/src/*.java"],
- apex_available: ["myapex"],
- permitted_packages: ["foo.bar", "bar.baz"],
- sdk_version: "none",
- system_modules: "none",
- min_sdk_version: "current",
- }
- apex {
- name: "myapex",
- min_sdk_version: "current",
- key: "myapex.key",
- java_libs: ["bcp_lib1", "bcp_lib2"],
- updatable: false,
- }
- `,
- bootJars: []string{"bcp_lib1", "bcp_lib2"},
- modulesPackages: map[string][]string{
- "myapex": []string{
- "foo.bar",
- },
- },
- },
- }
- for _, tc := range testcases {
- t.Run(tc.name, func(t *testing.T) {
- rules := createApexPermittedPackagesRules(tc.modulesPackages)
- testApexPermittedPackagesRules(t, tc.expectedError, tc.bp, tc.bootJars, rules)
- })
- }
- }
- func TestTestFor(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "myprivlib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1"],
- },
- apex_available: ["myapex"],
- }
- cc_library {
- name: "myprivlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: ["myapex"],
- }
- cc_test {
- name: "mytest",
- gtest: false,
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- shared_libs: ["mylib", "myprivlib", "mytestlib"],
- test_for: ["myapex"]
- }
- cc_library {
- name: "mytestlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- shared_libs: ["mylib", "myprivlib"],
- stl: "none",
- test_for: ["myapex"],
- }
- cc_benchmark {
- name: "mybench",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- shared_libs: ["mylib", "myprivlib"],
- stl: "none",
- test_for: ["myapex"],
- }
- `)
- ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) {
- ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").Args["libFlags"], " ")
- mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) })
- android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags)
- }
- // These modules are tests for the apex, therefore are linked to the
- // actual implementation of mylib instead of its stub.
- ensureLinkedLibIs("mytest", "android_arm64_armv8-a", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
- ensureLinkedLibIs("mytestlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
- ensureLinkedLibIs("mybench", "android_arm64_armv8-a", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
- }
- func TestIndirectTestFor(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib", "myprivlib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1"],
- },
- apex_available: ["myapex"],
- }
- cc_library {
- name: "myprivlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- shared_libs: ["mylib"],
- apex_available: ["myapex"],
- }
- cc_library {
- name: "mytestlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- shared_libs: ["myprivlib"],
- stl: "none",
- test_for: ["myapex"],
- }
- `)
- ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) {
- ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").Args["libFlags"], " ")
- mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) })
- android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags)
- }
- // The platform variant of mytestlib links to the platform variant of the
- // internal myprivlib.
- ensureLinkedLibIs("mytestlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/myprivlib/", "android_arm64_armv8-a_shared/myprivlib.so")
- // The platform variant of myprivlib links to the platform variant of mylib
- // and bypasses its stubs.
- ensureLinkedLibIs("myprivlib", "android_arm64_armv8-a_shared", "out/soong/.intermediates/mylib/", "android_arm64_armv8-a_shared/mylib.so")
- }
- func TestTestForForLibInOtherApex(t *testing.T) {
- // This case is only allowed for known overlapping APEXes, i.e. the ART APEXes.
- _ = testApex(t, `
- apex {
- name: "com.android.art",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex {
- name: "com.android.art.debug",
- key: "myapex.key",
- native_shared_libs: ["mylib", "mytestlib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1"],
- },
- apex_available: ["com.android.art", "com.android.art.debug"],
- }
- cc_library {
- name: "mytestlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- shared_libs: ["mylib"],
- stl: "none",
- apex_available: ["com.android.art.debug"],
- test_for: ["com.android.art"],
- }
- `,
- android.MockFS{
- "system/sepolicy/apex/com.android.art-file_contexts": nil,
- "system/sepolicy/apex/com.android.art.debug-file_contexts": nil,
- }.AddToFixture())
- }
- // TODO(jungjw): Move this to proptools
- func intPtr(i int) *int {
- return &i
- }
- func TestApexSet(t *testing.T) {
- ctx := testApex(t, `
- apex_set {
- name: "myapex",
- set: "myapex.apks",
- filename: "foo_v2.apex",
- overrides: ["foo"],
- }
- `,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_sdk_version = intPtr(30)
- }),
- android.FixtureModifyConfig(func(config android.Config) {
- config.Targets[android.Android] = []android.Target{
- {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}},
- {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}},
- }
- }),
- )
- m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
- // Check extract_apks tool parameters.
- extractedApex := m.Output("extracted/myapex.apks")
- actual := extractedApex.Args["abis"]
- expected := "ARMEABI_V7A,ARM64_V8A"
- if actual != expected {
- t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual)
- }
- actual = extractedApex.Args["sdk-version"]
- expected = "30"
- if actual != expected {
- t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual)
- }
- m = ctx.ModuleForTests("myapex", "android_common_myapex")
- a := m.Module().(*ApexSet)
- expectedOverrides := []string{"foo"}
- actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
- if !reflect.DeepEqual(actualOverrides, expectedOverrides) {
- t.Errorf("Incorrect LOCAL_OVERRIDES_MODULES - expected %q vs actual %q", expectedOverrides, actualOverrides)
- }
- }
- func TestNoStaticLinkingToStubsLib(t *testing.T) {
- testApexError(t, `.*required by "mylib" is a native library providing stub.*`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- static_libs: ["otherlib"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
- cc_library {
- name: "otherlib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1", "2", "3"],
- },
- apex_available: [ "myapex" ],
- }
- `)
- }
- func TestApexKeysTxt(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- custom_sign_tool: "sign_myapex",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `)
- apexKeysText := ctx.SingletonForTests("apex_keys_text")
- content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"]
- ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system_ext" sign_tool="sign_myapex"`)
- }
- func TestApexKeysTxtOverrides(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- custom_sign_tool: "sign_myapex",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- prebuilt_apex {
- name: "myapex",
- prefer: true,
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- }
- apex_set {
- name: "myapex_set",
- set: "myapex.apks",
- filename: "myapex_set.apex",
- overrides: ["myapex"],
- }
- `)
- apexKeysText := ctx.SingletonForTests("apex_keys_text")
- content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"]
- ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
- ensureContains(t, content, `name="myapex.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
- }
- func TestAllowedFiles(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- apps: ["app"],
- allowed_files: "allowed.txt",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- android_app {
- name: "app",
- srcs: ["foo/bar/MyClass.java"],
- package_name: "foo",
- sdk_version: "none",
- system_modules: "none",
- apex_available: [ "myapex" ],
- }
- `, withFiles(map[string][]byte{
- "sub/Android.bp": []byte(`
- override_apex {
- name: "override_myapex",
- base: "myapex",
- apps: ["override_app"],
- allowed_files: ":allowed",
- }
- // Overridable "path" property should be referenced indirectly
- filegroup {
- name: "allowed",
- srcs: ["allowed.txt"],
- }
- override_android_app {
- name: "override_app",
- base: "app",
- package_name: "bar",
- }
- `),
- }))
- rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("diffApexContentRule")
- if expected, actual := "allowed.txt", rule.Args["allowed_files_file"]; expected != actual {
- t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
- }
- rule2 := ctx.ModuleForTests("myapex", "android_common_override_myapex_myapex_image").Rule("diffApexContentRule")
- if expected, actual := "sub/allowed.txt", rule2.Args["allowed_files_file"]; expected != actual {
- t.Errorf("allowed_files_file: expected %q but got %q", expected, actual)
- }
- }
- func TestNonPreferredPrebuiltDependency(t *testing.T) {
- testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- stubs: {
- versions: ["current"],
- },
- apex_available: ["myapex"],
- }
- cc_prebuilt_library_shared {
- name: "mylib",
- prefer: false,
- srcs: ["prebuilt.so"],
- stubs: {
- versions: ["current"],
- },
- apex_available: ["myapex"],
- }
- `)
- }
- func TestCompressedApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- compressible: true,
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.CompressedApex = proptools.BoolPtr(true)
- }),
- )
- compressRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("compressRule")
- ensureContains(t, compressRule.Output.String(), "myapex.capex.unsigned")
- signApkRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Description("sign compressedApex")
- ensureEquals(t, signApkRule.Input.String(), compressRule.Output.String())
- // Make sure output of bundle is .capex
- ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- ensureContains(t, ab.outputFile.String(), "myapex.capex")
- // Verify android.mk rules
- data := android.AndroidMkDataForTest(t, ctx, ab)
- var builder strings.Builder
- data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.capex\n")
- }
- func TestPreferredPrebuiltSharedLibDep(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- apex_available: ["myapex"],
- shared_libs: ["otherlib"],
- system_shared_libs: [],
- }
- cc_library {
- name: "otherlib",
- srcs: ["mylib.cpp"],
- stubs: {
- versions: ["current"],
- },
- }
- cc_prebuilt_library_shared {
- name: "otherlib",
- prefer: true,
- srcs: ["prebuilt.so"],
- stubs: {
- versions: ["current"],
- },
- }
- `)
- ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, ab)
- var builder strings.Builder
- data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data)
- androidMk := builder.String()
- // The make level dependency needs to be on otherlib - prebuilt_otherlib isn't
- // a thing there.
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherlib\n")
- }
- func TestExcludeDependency(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- apex_available: ["myapex"],
- shared_libs: ["mylib2"],
- target: {
- apex: {
- exclude_shared_libs: ["mylib2"],
- },
- },
- }
- cc_library {
- name: "mylib2",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- }
- `)
- // Check if mylib is linked to mylib2 for the non-apex target
- ldFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared").Rule("ld").Args["libFlags"]
- ensureContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- // Make sure that the link doesn't occur for the apex target
- ldFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
- ensureNotContains(t, ldFlags, "mylib2/android_arm64_armv8-a_shared_apex10000/mylib2.so")
- // It shouldn't appear in the copy cmd as well.
- copyCmds := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule").Args["copy_commands"]
- ensureNotContains(t, copyCmds, "image.apex/lib64/mylib2.so")
- }
- func TestPrebuiltStubLibDep(t *testing.T) {
- bpBase := `
- apex {
- name: "myapex",
- key: "myapex.key",
- native_shared_libs: ["mylib"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- apex_available: ["myapex"],
- shared_libs: ["stublib"],
- system_shared_libs: [],
- }
- apex {
- name: "otherapex",
- enabled: %s,
- key: "myapex.key",
- native_shared_libs: ["stublib"],
- updatable: false,
- }
- `
- stublibSourceBp := `
- cc_library {
- name: "stublib",
- srcs: ["mylib.cpp"],
- apex_available: ["otherapex"],
- system_shared_libs: [],
- stl: "none",
- stubs: {
- versions: ["1"],
- },
- }
- `
- stublibPrebuiltBp := `
- cc_prebuilt_library_shared {
- name: "stublib",
- srcs: ["prebuilt.so"],
- apex_available: ["otherapex"],
- stubs: {
- versions: ["1"],
- },
- %s
- }
- `
- tests := []struct {
- name string
- stublibBp string
- usePrebuilt bool
- modNames []string // Modules to collect AndroidMkEntries for
- otherApexEnabled []string
- }{
- {
- name: "only_source",
- stublibBp: stublibSourceBp,
- usePrebuilt: false,
- modNames: []string{"stublib"},
- otherApexEnabled: []string{"true", "false"},
- },
- {
- name: "source_preferred",
- stublibBp: stublibSourceBp + fmt.Sprintf(stublibPrebuiltBp, ""),
- usePrebuilt: false,
- modNames: []string{"stublib", "prebuilt_stublib"},
- otherApexEnabled: []string{"true", "false"},
- },
- {
- name: "prebuilt_preferred",
- stublibBp: stublibSourceBp + fmt.Sprintf(stublibPrebuiltBp, "prefer: true,"),
- usePrebuilt: true,
- modNames: []string{"stublib", "prebuilt_stublib"},
- otherApexEnabled: []string{"false"}, // No "true" since APEX cannot depend on prebuilt.
- },
- {
- name: "only_prebuilt",
- stublibBp: fmt.Sprintf(stublibPrebuiltBp, ""),
- usePrebuilt: true,
- modNames: []string{"stublib"},
- otherApexEnabled: []string{"false"}, // No "true" since APEX cannot depend on prebuilt.
- },
- }
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- for _, otherApexEnabled := range test.otherApexEnabled {
- t.Run("otherapex_enabled_"+otherApexEnabled, func(t *testing.T) {
- ctx := testApex(t, fmt.Sprintf(bpBase, otherApexEnabled)+test.stublibBp)
- type modAndMkEntries struct {
- mod *cc.Module
- mkEntries android.AndroidMkEntries
- }
- entries := []*modAndMkEntries{}
- // Gather shared lib modules that are installable
- for _, modName := range test.modNames {
- for _, variant := range ctx.ModuleVariantsForTests(modName) {
- if !strings.HasPrefix(variant, "android_arm64_armv8-a_shared") {
- continue
- }
- mod := ctx.ModuleForTests(modName, variant).Module().(*cc.Module)
- if !mod.Enabled() || mod.IsHideFromMake() {
- continue
- }
- for _, ent := range android.AndroidMkEntriesForTest(t, ctx, mod) {
- if ent.Disabled {
- continue
- }
- entries = append(entries, &modAndMkEntries{
- mod: mod,
- mkEntries: ent,
- })
- }
- }
- }
- var entry *modAndMkEntries = nil
- for _, ent := range entries {
- if strings.Join(ent.mkEntries.EntryMap["LOCAL_MODULE"], ",") == "stublib" {
- if entry != nil {
- t.Errorf("More than one AndroidMk entry for \"stublib\": %s and %s", entry.mod, ent.mod)
- } else {
- entry = ent
- }
- }
- }
- if entry == nil {
- t.Errorf("AndroidMk entry for \"stublib\" missing")
- } else {
- isPrebuilt := entry.mod.Prebuilt() != nil
- if isPrebuilt != test.usePrebuilt {
- t.Errorf("Wrong module for \"stublib\" AndroidMk entry: got prebuilt %t, want prebuilt %t", isPrebuilt, test.usePrebuilt)
- }
- if !entry.mod.IsStubs() {
- t.Errorf("Module for \"stublib\" AndroidMk entry isn't a stub: %s", entry.mod)
- }
- if entry.mkEntries.EntryMap["LOCAL_NOT_AVAILABLE_FOR_PLATFORM"] != nil {
- t.Errorf("AndroidMk entry for \"stublib\" has LOCAL_NOT_AVAILABLE_FOR_PLATFORM set: %+v", entry.mkEntries)
- }
- cflags := entry.mkEntries.EntryMap["LOCAL_EXPORT_CFLAGS"]
- expected := "-D__STUBLIB_API__=10000"
- if !android.InList(expected, cflags) {
- t.Errorf("LOCAL_EXPORT_CFLAGS expected to have %q, but got %q", expected, cflags)
- }
- }
- })
- }
- })
- }
- }
- func TestHostApexInHostOnlyBuild(t *testing.T) {
- testApex(t, `
- apex {
- name: "myapex",
- host_supported: true,
- key: "myapex.key",
- updatable: false,
- payload_type: "zip",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- `,
- android.FixtureModifyConfig(func(config android.Config) {
- // We may not have device targets in all builds, e.g. in
- // prebuilts/build-tools/build-prebuilts.sh
- config.Targets[android.Android] = []android.Target{}
- }))
- }
- func TestApexJavaCoverage(t *testing.T) {
- bp := `
- apex {
- name: "myapex",
- key: "myapex.key",
- java_libs: ["mylib"],
- bootclasspath_fragments: ["mybootclasspathfragment"],
- systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "mylib",
- srcs: ["mylib.java"],
- apex_available: ["myapex"],
- compile_dex: true,
- }
- bootclasspath_fragment {
- name: "mybootclasspathfragment",
- contents: ["mybootclasspathlib"],
- apex_available: ["myapex"],
- }
- java_library {
- name: "mybootclasspathlib",
- srcs: ["mybootclasspathlib.java"],
- apex_available: ["myapex"],
- compile_dex: true,
- }
- systemserverclasspath_fragment {
- name: "mysystemserverclasspathfragment",
- contents: ["mysystemserverclasspathlib"],
- apex_available: ["myapex"],
- }
- java_library {
- name: "mysystemserverclasspathlib",
- srcs: ["mysystemserverclasspathlib.java"],
- apex_available: ["myapex"],
- compile_dex: true,
- }
- `
- result := android.GroupFixturePreparers(
- PrepareForTestWithApexBuildComponents,
- prepareForTestWithMyapex,
- java.PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAndroidBuildComponents,
- android.FixtureWithRootAndroidBp(bp),
- dexpreopt.FixtureSetApexBootJars("myapex:mybootclasspathlib"),
- dexpreopt.FixtureSetApexSystemServerJars("myapex:mysystemserverclasspathlib"),
- android.FixtureMergeEnv(map[string]string{
- "EMMA_INSTRUMENT": "true",
- }),
- ).RunTest(t)
- // Make sure jacoco ran on both mylib and mybootclasspathlib
- if result.ModuleForTests("mylib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
- t.Errorf("Failed to find jacoco rule for mylib")
- }
- if result.ModuleForTests("mybootclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
- t.Errorf("Failed to find jacoco rule for mybootclasspathlib")
- }
- if result.ModuleForTests("mysystemserverclasspathlib", "android_common_apex10000").MaybeRule("jacoco").Rule == nil {
- t.Errorf("Failed to find jacoco rule for mysystemserverclasspathlib")
- }
- }
- func TestProhibitStaticExecutable(t *testing.T) {
- testApexError(t, `executable mybin is static`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- binaries: ["mybin"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- cc_binary {
- name: "mybin",
- srcs: ["mylib.cpp"],
- relative_install_path: "foo/bar",
- static_executable: true,
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- min_sdk_version: "29",
- }
- `)
- testApexError(t, `executable mybin.rust is static`, `
- apex {
- name: "myapex",
- key: "myapex.key",
- binaries: ["mybin.rust"],
- min_sdk_version: "29",
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- rust_binary {
- name: "mybin.rust",
- srcs: ["foo.rs"],
- static_executable: true,
- apex_available: ["myapex"],
- min_sdk_version: "29",
- }
- `)
- }
- func TestAndroidMk_DexpreoptBuiltInstalledForApex(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- java_libs: ["foo"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "foo",
- srcs: ["foo.java"],
- apex_available: ["myapex"],
- installable: true,
- }
- `,
- dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
- )
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- var builder strings.Builder
- data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex")
- }
- func TestAndroidMk_DexpreoptBuiltInstalledForApex_Prebuilt(t *testing.T) {
- ctx := testApex(t, `
- prebuilt_apex {
- name: "myapex",
- arch: {
- arm64: {
- src: "myapex-arm64.apex",
- },
- arm: {
- src: "myapex-arm.apex",
- },
- },
- exported_java_libs: ["foo"],
- }
- java_import {
- name: "foo",
- jars: ["foo.jar"],
- installable: true,
- }
- `,
- dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
- )
- prebuilt := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*Prebuilt)
- entriesList := android.AndroidMkEntriesForTest(t, ctx, prebuilt)
- mainModuleEntries := entriesList[0]
- android.AssertArrayString(t,
- "LOCAL_REQUIRED_MODULES",
- mainModuleEntries.EntryMap["LOCAL_REQUIRED_MODULES"],
- []string{
- "foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex",
- "foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex",
- })
- }
- func TestAndroidMk_RequiredModules(t *testing.T) {
- ctx := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- updatable: false,
- java_libs: ["foo"],
- required: ["otherapex"],
- }
- apex {
- name: "otherapex",
- key: "myapex.key",
- updatable: false,
- java_libs: ["foo"],
- required: ["otherapex"],
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- java_library {
- name: "foo",
- srcs: ["foo.java"],
- apex_available: ["myapex", "otherapex"],
- installable: true,
- }
- `)
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
- var builder strings.Builder
- data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data)
- androidMk := builder.String()
- ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES += otherapex")
- }
- func TestSdkLibraryCanHaveHigherMinSdkVersion(t *testing.T) {
- preparer := android.GroupFixturePreparers(
- PrepareForTestWithApexBuildComponents,
- prepareForTestWithMyapex,
- java.PrepareForTestWithJavaSdkLibraryFiles,
- java.PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAndroidBuildComponents,
- dexpreopt.FixtureSetApexBootJars("myapex:mybootclasspathlib"),
- dexpreopt.FixtureSetApexSystemServerJars("myapex:mysystemserverclasspathlib"),
- )
- // Test java_sdk_library in bootclasspath_fragment may define higher min_sdk_version than the apex
- t.Run("bootclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
- preparer.RunTestWithBp(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- bootclasspath_fragments: ["mybootclasspathfragment"],
- min_sdk_version: "30",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- bootclasspath_fragment {
- name: "mybootclasspathfragment",
- contents: ["mybootclasspathlib"],
- apex_available: ["myapex"],
- }
- java_sdk_library {
- name: "mybootclasspathlib",
- srcs: ["mybootclasspathlib.java"],
- apex_available: ["myapex"],
- compile_dex: true,
- unsafe_ignore_missing_latest_api: true,
- min_sdk_version: "31",
- static_libs: ["util"],
- }
- java_library {
- name: "util",
- srcs: ["a.java"],
- apex_available: ["myapex"],
- min_sdk_version: "31",
- static_libs: ["another_util"],
- }
- java_library {
- name: "another_util",
- srcs: ["a.java"],
- min_sdk_version: "31",
- apex_available: ["myapex"],
- }
- `)
- })
- // Test java_sdk_library in systemserverclasspath_fragment may define higher min_sdk_version than the apex
- t.Run("systemserverclasspath_fragment jar has higher min_sdk_version than apex", func(t *testing.T) {
- preparer.RunTestWithBp(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
- min_sdk_version: "30",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- systemserverclasspath_fragment {
- name: "mysystemserverclasspathfragment",
- contents: ["mysystemserverclasspathlib"],
- apex_available: ["myapex"],
- }
- java_sdk_library {
- name: "mysystemserverclasspathlib",
- srcs: ["mysystemserverclasspathlib.java"],
- apex_available: ["myapex"],
- compile_dex: true,
- min_sdk_version: "32",
- unsafe_ignore_missing_latest_api: true,
- static_libs: ["util"],
- }
- java_library {
- name: "util",
- srcs: ["a.java"],
- apex_available: ["myapex"],
- min_sdk_version: "31",
- static_libs: ["another_util"],
- }
- java_library {
- name: "another_util",
- srcs: ["a.java"],
- min_sdk_version: "31",
- apex_available: ["myapex"],
- }
- `)
- })
- t.Run("bootclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
- preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mybootclasspathlib".*must set min_sdk_version`)).
- RunTestWithBp(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- bootclasspath_fragments: ["mybootclasspathfragment"],
- min_sdk_version: "30",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- bootclasspath_fragment {
- name: "mybootclasspathfragment",
- contents: ["mybootclasspathlib"],
- apex_available: ["myapex"],
- }
- java_sdk_library {
- name: "mybootclasspathlib",
- srcs: ["mybootclasspathlib.java"],
- apex_available: ["myapex"],
- compile_dex: true,
- unsafe_ignore_missing_latest_api: true,
- }
- `)
- })
- t.Run("systemserverclasspath_fragment jar must set min_sdk_version", func(t *testing.T) {
- preparer.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "mysystemserverclasspathlib".*must set min_sdk_version`)).
- RunTestWithBp(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
- min_sdk_version: "30",
- updatable: false,
- }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
- systemserverclasspath_fragment {
- name: "mysystemserverclasspathfragment",
- contents: ["mysystemserverclasspathlib"],
- apex_available: ["myapex"],
- }
- java_sdk_library {
- name: "mysystemserverclasspathlib",
- srcs: ["mysystemserverclasspathlib.java"],
- apex_available: ["myapex"],
- compile_dex: true,
- unsafe_ignore_missing_latest_api: true,
- }
- `)
- })
- }
- func TestMain(m *testing.M) {
- os.Exit(m.Run())
- }
|