12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629 |
- // Copyright 2017 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 java
- import (
- "fmt"
- "path/filepath"
- "reflect"
- "sort"
- "strings"
- "testing"
- "github.com/google/blueprint/proptools"
- "android/soong/android"
- "android/soong/cc"
- "android/soong/dexpreopt"
- )
- // testApp runs tests using the prepareForJavaTest
- //
- // See testJava for an explanation as to how to stop using this deprecated method.
- //
- // deprecated
- func testApp(t *testing.T, bp string) *android.TestContext {
- t.Helper()
- result := prepareForJavaTest.RunTestWithBp(t, bp)
- return result.TestContext
- }
- func TestApp(t *testing.T) {
- resourceFiles := []string{
- "res/layout/layout.xml",
- "res/values/strings.xml",
- "res/values-en-rUS/strings.xml",
- }
- compiledResourceFiles := []string{
- "aapt2/res/layout_layout.xml.flat",
- "aapt2/res/values_strings.arsc.flat",
- "aapt2/res/values-en-rUS_strings.arsc.flat",
- }
- for _, moduleType := range []string{"android_app", "android_library"} {
- t.Run(moduleType, func(t *testing.T) {
- result := android.GroupFixturePreparers(
- prepareForJavaTest,
- android.FixtureModifyMockFS(func(fs android.MockFS) {
- for _, file := range resourceFiles {
- fs[file] = nil
- }
- }),
- ).RunTestWithBp(t, moduleType+` {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current"
- }
- `)
- foo := result.ModuleForTests("foo", "android_common")
- var expectedLinkImplicits []string
- manifestFixer := foo.Output("manifest_fixer/AndroidManifest.xml")
- expectedLinkImplicits = append(expectedLinkImplicits, manifestFixer.Output.String())
- frameworkRes := result.ModuleForTests("framework-res", "android_common")
- expectedLinkImplicits = append(expectedLinkImplicits,
- frameworkRes.Output("package-res.apk").Output.String())
- // Test the mapping from input files to compiled output file names
- compile := foo.Output(compiledResourceFiles[0])
- android.AssertDeepEquals(t, "aapt2 compile inputs", resourceFiles, compile.Inputs.Strings())
- compiledResourceOutputs := compile.Outputs.Strings()
- sort.Strings(compiledResourceOutputs)
- expectedLinkImplicits = append(expectedLinkImplicits, compiledResourceOutputs...)
- list := foo.Output("aapt2/res.list")
- expectedLinkImplicits = append(expectedLinkImplicits, list.Output.String())
- // Check that the link rule uses
- res := result.ModuleForTests("foo", "android_common").Output("package-res.apk")
- android.AssertDeepEquals(t, "aapt2 link implicits", expectedLinkImplicits, res.Implicits.Strings())
- })
- }
- }
- func TestAppSplits(t *testing.T) {
- ctx := testApp(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- package_splits: ["v4", "v7,hdpi"],
- sdk_version: "current"
- }`)
- foo := ctx.ModuleForTests("foo", "android_common")
- expectedOutputs := []string{
- "out/soong/.intermediates/foo/android_common/foo.apk",
- "out/soong/.intermediates/foo/android_common/foo_v4.apk",
- "out/soong/.intermediates/foo/android_common/foo_v7_hdpi.apk",
- }
- for _, expectedOutput := range expectedOutputs {
- foo.Output(expectedOutput)
- }
- outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
- if err != nil {
- t.Fatal(err)
- }
- android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles)
- }
- func TestPlatformAPIs(t *testing.T) {
- testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- platform_apis: true,
- }
- `)
- testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `)
- testJavaError(t, "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true", `
- android_app {
- name: "bar",
- srcs: ["b.java"],
- }
- `)
- testJavaError(t, "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.", `
- android_app {
- name: "bar",
- srcs: ["b.java"],
- sdk_version: "system_current",
- platform_apis: true,
- }
- `)
- }
- func TestAndroidAppLinkType(t *testing.T) {
- testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- libs: ["bar"],
- static_libs: ["baz"],
- platform_apis: true,
- }
- java_library {
- name: "bar",
- sdk_version: "current",
- srcs: ["b.java"],
- }
- android_library {
- name: "baz",
- sdk_version: "system_current",
- srcs: ["c.java"],
- }
- `)
- testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- libs: ["bar"],
- sdk_version: "current",
- static_libs: ["baz"],
- }
- java_library {
- name: "bar",
- sdk_version: "current",
- srcs: ["b.java"],
- }
- android_library {
- name: "baz",
- sdk_version: "system_current",
- srcs: ["c.java"],
- }
- `)
- testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- libs: ["bar"],
- sdk_version: "system_current",
- static_libs: ["baz"],
- }
- java_library {
- name: "bar",
- sdk_version: "current",
- srcs: ["b.java"],
- }
- android_library {
- name: "baz",
- sdk_version: "system_current",
- srcs: ["c.java"],
- }
- `)
- testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- libs: ["bar"],
- sdk_version: "system_current",
- static_libs: ["baz"],
- }
- java_library {
- name: "bar",
- sdk_version: "current",
- srcs: ["b.java"],
- }
- android_library {
- name: "baz",
- srcs: ["c.java"],
- }
- `)
- }
- func TestUpdatableApps(t *testing.T) {
- testCases := []struct {
- name string
- bp string
- expectedError string
- }{
- {
- name: "Stable public SDK",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "29",
- min_sdk_version: "29",
- updatable: true,
- }`,
- },
- {
- name: "Stable system SDK",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "system_29",
- min_sdk_version: "29",
- updatable: true,
- }`,
- },
- {
- name: "Current public SDK",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- min_sdk_version: "29",
- updatable: true,
- }`,
- },
- {
- name: "Current system SDK",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "system_current",
- min_sdk_version: "29",
- updatable: true,
- }`,
- },
- {
- name: "Current module SDK",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "module_current",
- min_sdk_version: "29",
- updatable: true,
- }`,
- },
- {
- name: "Current core SDK",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "core_current",
- min_sdk_version: "29",
- updatable: true,
- }`,
- },
- {
- name: "No Platform APIs",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- platform_apis: true,
- min_sdk_version: "29",
- updatable: true,
- }`,
- expectedError: "Updatable apps must use stable SDKs",
- },
- {
- name: "No Core Platform APIs",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "core_platform",
- min_sdk_version: "29",
- updatable: true,
- }`,
- expectedError: "Updatable apps must use stable SDKs",
- },
- {
- name: "No unspecified APIs",
- bp: `android_app {
- name: "foo",
- srcs: ["a.java"],
- updatable: true,
- min_sdk_version: "29",
- }`,
- expectedError: "Updatable apps must use stable SDK",
- },
- {
- name: "Must specify min_sdk_version",
- bp: `android_app {
- name: "app_without_min_sdk_version",
- srcs: ["a.java"],
- sdk_version: "29",
- updatable: true,
- }`,
- expectedError: "updatable apps must set min_sdk_version.",
- },
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- errorHandler := android.FixtureExpectsNoErrors
- if test.expectedError != "" {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError)
- }
- android.GroupFixturePreparers(
- prepareForJavaTest, FixtureWithPrebuiltApis(map[string][]string{
- "29": {"foo"},
- })).
- ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, test.bp)
- })
- }
- }
- func TestUpdatableApps_TransitiveDepsShouldSetMinSdkVersion(t *testing.T) {
- testJavaError(t, `module "bar".*: should support min_sdk_version\(29\)`, cc.GatherRequiredDepsForTest(android.Android)+`
- android_app {
- name: "foo",
- srcs: ["a.java"],
- updatable: true,
- sdk_version: "current",
- min_sdk_version: "29",
- static_libs: ["bar"],
- }
- java_library {
- name: "bar",
- sdk_version: "current",
- }
- `)
- }
- func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) {
- testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
- android_app {
- name: "foo",
- srcs: ["a.java"],
- updatable: true,
- sdk_version: "current",
- min_sdk_version: "current",
- jni_libs: ["libjni"],
- }
- cc_library {
- name: "libjni",
- stl: "none",
- system_shared_libs: [],
- sdk_version: "current",
- }
- `)
- }
- func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) {
- bp := cc.GatherRequiredDepsForTest(android.Android) + `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- updatable: true,
- sdk_version: "current",
- min_sdk_version: "29",
- jni_libs: ["libjni"],
- }
- cc_library {
- name: "libjni",
- stl: "none",
- system_shared_libs: [],
- sdk_version: "current",
- min_sdk_version: "29",
- }
- `
- fs := map[string][]byte{
- "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil,
- "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": nil,
- "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o": nil,
- "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o": nil,
- }
- ctx, _ := testJavaWithFS(t, bp, fs)
- inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits
- var crtbeginFound, crtendFound bool
- expectedCrtBegin := ctx.ModuleForTests("crtbegin_so",
- "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
- expectedCrtEnd := ctx.ModuleForTests("crtend_so",
- "android_arm64_armv8-a_sdk_29").Rule("noAddrSig").Output
- implicits := []string{}
- for _, input := range inputs {
- implicits = append(implicits, input.String())
- if strings.HasSuffix(input.String(), expectedCrtBegin.String()) {
- crtbeginFound = true
- } else if strings.HasSuffix(input.String(), expectedCrtEnd.String()) {
- crtendFound = true
- }
- }
- if !crtbeginFound {
- t.Error(fmt.Sprintf(
- "expected implicit with suffix %q, have the following implicits:\n%s",
- expectedCrtBegin, strings.Join(implicits, "\n")))
- }
- if !crtendFound {
- t.Error(fmt.Sprintf(
- "expected implicit with suffix %q, have the following implicits:\n%s",
- expectedCrtEnd, strings.Join(implicits, "\n")))
- }
- }
- func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) {
- bp := cc.GatherRequiredDepsForTest(android.Android) + `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- updatable: true,
- sdk_version: "current",
- min_sdk_version: "29", // this APK should support 29
- jni_libs: ["libjni"],
- }
- cc_library {
- name: "libjni",
- stl: "none",
- sdk_version: "current",
- min_sdk_version: "current",
- }
- `
- testJavaError(t, `"libjni" .*: min_sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp)
- }
- func TestUpdatableApps_ErrorIfDepMinSdkVersionIsHigher(t *testing.T) {
- bp := cc.GatherRequiredDepsForTest(android.Android) + `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- updatable: true,
- sdk_version: "current",
- min_sdk_version: "29", // this APK should support 29
- jni_libs: ["libjni"],
- }
- cc_library {
- name: "libjni",
- stl: "none",
- shared_libs: ["libbar"],
- system_shared_libs: [],
- sdk_version: "27",
- min_sdk_version: "27",
- }
- cc_library {
- name: "libbar",
- stl: "none",
- system_shared_libs: [],
- sdk_version: "current",
- min_sdk_version: "current",
- }
- `
- testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp)
- }
- func TestResourceDirs(t *testing.T) {
- testCases := []struct {
- name string
- prop string
- resources []string
- }{
- {
- name: "no resource_dirs",
- prop: "",
- resources: []string{"res/res/values/strings.xml"},
- },
- {
- name: "resource_dirs",
- prop: `resource_dirs: ["res"]`,
- resources: []string{"res/res/values/strings.xml"},
- },
- {
- name: "empty resource_dirs",
- prop: `resource_dirs: []`,
- resources: nil,
- },
- }
- fs := android.MockFS{
- "res/res/values/strings.xml": nil,
- }
- bp := `
- android_app {
- name: "foo",
- sdk_version: "current",
- %s
- }
- `
- for _, testCase := range testCases {
- t.Run(testCase.name, func(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithOverlayBuildComponents,
- fs.AddToFixture(),
- ).RunTestWithBp(t, fmt.Sprintf(bp, testCase.prop))
- module := result.ModuleForTests("foo", "android_common")
- resourceList := module.MaybeOutput("aapt2/res.list")
- var resources []string
- if resourceList.Rule != nil {
- for _, compiledResource := range resourceList.Inputs.Strings() {
- resources = append(resources, module.Output(compiledResource).Inputs.Strings()...)
- }
- }
- android.AssertDeepEquals(t, "resource files", testCase.resources, resources)
- })
- }
- }
- func TestLibraryAssets(t *testing.T) {
- bp := `
- android_app {
- name: "foo",
- sdk_version: "current",
- static_libs: ["lib1", "lib2", "lib3"],
- }
- android_library {
- name: "lib1",
- sdk_version: "current",
- asset_dirs: ["assets_a"],
- }
- android_library {
- name: "lib2",
- sdk_version: "current",
- }
- android_library {
- name: "lib3",
- sdk_version: "current",
- static_libs: ["lib4"],
- }
- android_library {
- name: "lib4",
- sdk_version: "current",
- asset_dirs: ["assets_b"],
- }
- `
- testCases := []struct {
- name string
- assetFlag string
- assetPackages []string
- }{
- {
- name: "foo",
- // lib1 has its own asset. lib3 doesn't have any, but provides lib4's transitively.
- assetPackages: []string{
- "out/soong/.intermediates/foo/android_common/aapt2/package-res.apk",
- "out/soong/.intermediates/lib1/android_common/assets.zip",
- "out/soong/.intermediates/lib3/android_common/assets.zip",
- },
- },
- {
- name: "lib1",
- assetFlag: "-A assets_a",
- },
- {
- name: "lib2",
- },
- {
- name: "lib3",
- assetPackages: []string{
- "out/soong/.intermediates/lib3/android_common/aapt2/package-res.apk",
- "out/soong/.intermediates/lib4/android_common/assets.zip",
- },
- },
- {
- name: "lib4",
- assetFlag: "-A assets_b",
- },
- }
- ctx := testApp(t, bp)
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- m := ctx.ModuleForTests(test.name, "android_common")
- // Check asset flag in aapt2 link flags
- var aapt2link android.TestingBuildParams
- if len(test.assetPackages) > 0 {
- aapt2link = m.Output("aapt2/package-res.apk")
- } else {
- aapt2link = m.Output("package-res.apk")
- }
- aapt2link = aapt2link
- aapt2Flags := aapt2link.Args["flags"]
- if test.assetFlag != "" {
- android.AssertStringDoesContain(t, "asset flag", aapt2Flags, test.assetFlag)
- } else {
- android.AssertStringDoesNotContain(t, "aapt2 link flags", aapt2Flags, " -A ")
- }
- // Check asset merge rule.
- if len(test.assetPackages) > 0 {
- mergeAssets := m.Output("package-res.apk")
- android.AssertPathsRelativeToTopEquals(t, "mergeAssets inputs", test.assetPackages, mergeAssets.Inputs)
- }
- })
- }
- }
- func TestAppJavaResources(t *testing.T) {
- bp := `
- android_app {
- name: "foo",
- sdk_version: "current",
- java_resources: ["resources/a"],
- srcs: ["a.java"],
- }
- android_app {
- name: "bar",
- sdk_version: "current",
- java_resources: ["resources/a"],
- }
- `
- ctx := testApp(t, bp)
- foo := ctx.ModuleForTests("foo", "android_common")
- fooResources := foo.Output("res/foo.jar")
- fooDexJar := foo.Output("dex-withres/foo.jar")
- fooDexJarAligned := foo.Output("dex-withres-aligned/foo.jar")
- fooApk := foo.Rule("combineApk")
- if g, w := fooDexJar.Inputs.Strings(), fooResources.Output.String(); !android.InList(w, g) {
- t.Errorf("expected resource jar %q in foo dex jar inputs %q", w, g)
- }
- if g, w := fooDexJarAligned.Input.String(), fooDexJar.Output.String(); g != w {
- t.Errorf("expected dex jar %q in foo aligned dex jar inputs %q", w, g)
- }
- if g, w := fooApk.Inputs.Strings(), fooDexJarAligned.Output.String(); !android.InList(w, g) {
- t.Errorf("expected aligned dex jar %q in foo apk inputs %q", w, g)
- }
- bar := ctx.ModuleForTests("bar", "android_common")
- barResources := bar.Output("res/bar.jar")
- barApk := bar.Rule("combineApk")
- if g, w := barApk.Inputs.Strings(), barResources.Output.String(); !android.InList(w, g) {
- t.Errorf("expected resources jar %q in bar apk inputs %q", w, g)
- }
- }
- func TestAndroidResources(t *testing.T) {
- testCases := []struct {
- name string
- enforceRROTargets []string
- enforceRROExcludedOverlays []string
- resourceFiles map[string][]string
- overlayFiles map[string][]string
- rroDirs map[string][]string
- }{
- {
- name: "no RRO",
- enforceRROTargets: nil,
- enforceRROExcludedOverlays: nil,
- resourceFiles: map[string][]string{
- "foo": nil,
- "bar": {"bar/res/res/values/strings.xml"},
- "lib": nil,
- "lib2": {"lib2/res/res/values/strings.xml"},
- },
- overlayFiles: map[string][]string{
- "foo": {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
- "out/soong/.intermediates/lib/android_common/package-res.apk",
- "out/soong/.intermediates/lib3/android_common/package-res.apk",
- "foo/res/res/values/strings.xml",
- "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
- "device/vendor/blah/overlay/foo/res/values/strings.xml",
- "product/vendor/blah/overlay/foo/res/values/strings.xml",
- },
- "bar": {
- "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
- "device/vendor/blah/overlay/bar/res/values/strings.xml",
- },
- "lib": {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
- "lib/res/res/values/strings.xml",
- "device/vendor/blah/overlay/lib/res/values/strings.xml",
- },
- },
- rroDirs: map[string][]string{
- "foo": nil,
- "bar": nil,
- },
- },
- {
- name: "enforce RRO on foo",
- enforceRROTargets: []string{"foo"},
- enforceRROExcludedOverlays: []string{"device/vendor/blah/static_overlay"},
- resourceFiles: map[string][]string{
- "foo": nil,
- "bar": {"bar/res/res/values/strings.xml"},
- "lib": nil,
- "lib2": {"lib2/res/res/values/strings.xml"},
- },
- overlayFiles: map[string][]string{
- "foo": {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
- "out/soong/.intermediates/lib/android_common/package-res.apk",
- "out/soong/.intermediates/lib3/android_common/package-res.apk",
- "foo/res/res/values/strings.xml",
- "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
- },
- "bar": {
- "device/vendor/blah/static_overlay/bar/res/values/strings.xml",
- "device/vendor/blah/overlay/bar/res/values/strings.xml",
- },
- "lib": {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
- "lib/res/res/values/strings.xml",
- },
- },
- rroDirs: map[string][]string{
- "foo": {
- "device:device/vendor/blah/overlay/foo/res",
- "product:product/vendor/blah/overlay/foo/res",
- "device:device/vendor/blah/overlay/lib/res",
- },
- "bar": nil,
- "lib": {"device:device/vendor/blah/overlay/lib/res"},
- },
- },
- {
- name: "enforce RRO on all",
- enforceRROTargets: []string{"*"},
- enforceRROExcludedOverlays: []string{
- // Excluding specific apps/res directories also allowed.
- "device/vendor/blah/static_overlay/foo",
- "device/vendor/blah/static_overlay/bar/res",
- },
- resourceFiles: map[string][]string{
- "foo": nil,
- "bar": {"bar/res/res/values/strings.xml"},
- "lib": nil,
- "lib2": {"lib2/res/res/values/strings.xml"},
- },
- overlayFiles: map[string][]string{
- "foo": {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
- "out/soong/.intermediates/lib/android_common/package-res.apk",
- "out/soong/.intermediates/lib3/android_common/package-res.apk",
- "foo/res/res/values/strings.xml",
- "device/vendor/blah/static_overlay/foo/res/values/strings.xml",
- },
- "bar": {"device/vendor/blah/static_overlay/bar/res/values/strings.xml"},
- "lib": {
- "out/soong/.intermediates/lib2/android_common/package-res.apk",
- "lib/res/res/values/strings.xml",
- },
- },
- rroDirs: map[string][]string{
- "foo": {
- "device:device/vendor/blah/overlay/foo/res",
- "product:product/vendor/blah/overlay/foo/res",
- // Lib dep comes after the direct deps
- "device:device/vendor/blah/overlay/lib/res",
- },
- "bar": {"device:device/vendor/blah/overlay/bar/res"},
- "lib": {"device:device/vendor/blah/overlay/lib/res"},
- },
- },
- }
- deviceResourceOverlays := []string{
- "device/vendor/blah/overlay",
- "device/vendor/blah/overlay2",
- "device/vendor/blah/static_overlay",
- }
- productResourceOverlays := []string{
- "product/vendor/blah/overlay",
- }
- fs := android.MockFS{
- "foo/res/res/values/strings.xml": nil,
- "bar/res/res/values/strings.xml": nil,
- "lib/res/res/values/strings.xml": nil,
- "lib2/res/res/values/strings.xml": nil,
- "device/vendor/blah/overlay/foo/res/values/strings.xml": nil,
- "device/vendor/blah/overlay/bar/res/values/strings.xml": nil,
- "device/vendor/blah/overlay/lib/res/values/strings.xml": nil,
- "device/vendor/blah/static_overlay/foo/res/values/strings.xml": nil,
- "device/vendor/blah/static_overlay/bar/res/values/strings.xml": nil,
- "device/vendor/blah/overlay2/res/values/strings.xml": nil,
- "product/vendor/blah/overlay/foo/res/values/strings.xml": nil,
- }
- bp := `
- android_app {
- name: "foo",
- sdk_version: "current",
- resource_dirs: ["foo/res"],
- static_libs: ["lib", "lib3"],
- }
- android_app {
- name: "bar",
- sdk_version: "current",
- resource_dirs: ["bar/res"],
- }
- android_library {
- name: "lib",
- sdk_version: "current",
- resource_dirs: ["lib/res"],
- static_libs: ["lib2"],
- }
- android_library {
- name: "lib2",
- sdk_version: "current",
- resource_dirs: ["lib2/res"],
- }
- // This library has the same resources as lib (should not lead to dupe RROs)
- android_library {
- name: "lib3",
- sdk_version: "current",
- resource_dirs: ["lib/res"]
- }
- `
- for _, testCase := range testCases {
- t.Run(testCase.name, func(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- PrepareForTestWithOverlayBuildComponents,
- fs.AddToFixture(),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.DeviceResourceOverlays = deviceResourceOverlays
- variables.ProductResourceOverlays = productResourceOverlays
- if testCase.enforceRROTargets != nil {
- variables.EnforceRROTargets = testCase.enforceRROTargets
- }
- if testCase.enforceRROExcludedOverlays != nil {
- variables.EnforceRROExcludedOverlays = testCase.enforceRROExcludedOverlays
- }
- }),
- ).RunTestWithBp(t, bp)
- resourceListToFiles := func(module android.TestingModule, list []string) (files []string) {
- for _, o := range list {
- res := module.MaybeOutput(o)
- if res.Rule != nil {
- // If the overlay is compiled as part of this module (i.e. a .arsc.flat file),
- // verify the inputs to the .arsc.flat rule.
- files = append(files, res.Inputs.Strings()...)
- } else {
- // Otherwise, verify the full path to the output of the other module
- files = append(files, o)
- }
- }
- return files
- }
- getResources := func(moduleName string) (resourceFiles, overlayFiles, rroDirs []string) {
- module := result.ModuleForTests(moduleName, "android_common")
- resourceList := module.MaybeOutput("aapt2/res.list")
- if resourceList.Rule != nil {
- resourceFiles = resourceListToFiles(module, android.PathsRelativeToTop(resourceList.Inputs))
- }
- overlayList := module.MaybeOutput("aapt2/overlay.list")
- if overlayList.Rule != nil {
- overlayFiles = resourceListToFiles(module, android.PathsRelativeToTop(overlayList.Inputs))
- }
- for _, d := range module.Module().(AndroidLibraryDependency).ExportedRRODirs() {
- var prefix string
- if d.overlayType == device {
- prefix = "device:"
- } else if d.overlayType == product {
- prefix = "product:"
- } else {
- t.Fatalf("Unexpected overlayType %d", d.overlayType)
- }
- rroDirs = append(rroDirs, prefix+android.PathRelativeToTop(d.path))
- }
- return resourceFiles, overlayFiles, rroDirs
- }
- modules := []string{"foo", "bar", "lib", "lib2"}
- for _, module := range modules {
- resourceFiles, overlayFiles, rroDirs := getResources(module)
- if !reflect.DeepEqual(resourceFiles, testCase.resourceFiles[module]) {
- t.Errorf("expected %s resource files:\n %#v\n got:\n %#v",
- module, testCase.resourceFiles[module], resourceFiles)
- }
- if !reflect.DeepEqual(overlayFiles, testCase.overlayFiles[module]) {
- t.Errorf("expected %s overlay files:\n %#v\n got:\n %#v",
- module, testCase.overlayFiles[module], overlayFiles)
- }
- if !reflect.DeepEqual(rroDirs, testCase.rroDirs[module]) {
- t.Errorf("expected %s rroDirs: %#v\n got:\n %#v",
- module, testCase.rroDirs[module], rroDirs)
- }
- }
- })
- }
- }
- func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) {
- foo := result.ModuleForTests("foo", "android_common")
- link := foo.Output("package-res.apk")
- linkFlags := strings.Split(link.Args["flags"], " ")
- min := android.IndexList("--min-sdk-version", linkFlags)
- target := android.IndexList("--target-sdk-version", linkFlags)
- if min == -1 || target == -1 || min == len(linkFlags)-1 || target == len(linkFlags)-1 {
- t.Fatalf("missing --min-sdk-version or --target-sdk-version in link flags: %q", linkFlags)
- }
- gotMinSdkVersion := linkFlags[min+1]
- gotTargetSdkVersion := linkFlags[target+1]
- android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion)
- android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion)
- }
- func TestAppSdkVersion(t *testing.T) {
- testCases := []struct {
- name string
- sdkVersion string
- platformSdkInt int
- platformSdkCodename string
- platformSdkFinal bool
- minSdkVersionBp string
- expectedMinSdkVersion string
- platformApis bool
- activeCodenames []string
- }{
- {
- name: "current final SDK",
- sdkVersion: "current",
- platformSdkInt: 27,
- platformSdkCodename: "REL",
- platformSdkFinal: true,
- expectedMinSdkVersion: "27",
- },
- {
- name: "current non-final SDK",
- sdkVersion: "current",
- platformSdkInt: 27,
- platformSdkCodename: "OMR1",
- platformSdkFinal: false,
- expectedMinSdkVersion: "OMR1",
- activeCodenames: []string{"OMR1"},
- },
- {
- name: "default final SDK",
- sdkVersion: "",
- platformApis: true,
- platformSdkInt: 27,
- platformSdkCodename: "REL",
- platformSdkFinal: true,
- expectedMinSdkVersion: "27",
- },
- {
- name: "default non-final SDK",
- sdkVersion: "",
- platformApis: true,
- platformSdkInt: 27,
- platformSdkCodename: "OMR1",
- platformSdkFinal: false,
- expectedMinSdkVersion: "OMR1",
- activeCodenames: []string{"OMR1"},
- },
- {
- name: "14",
- sdkVersion: "14",
- expectedMinSdkVersion: "14",
- platformSdkCodename: "S",
- activeCodenames: []string{"S"},
- },
- {
- name: "two active SDKs",
- sdkVersion: "module_current",
- minSdkVersionBp: "UpsideDownCake",
- expectedMinSdkVersion: "UpsideDownCake", // And not VanillaIceCream
- platformSdkCodename: "VanillaIceCream",
- activeCodenames: []string{"UpsideDownCake", "VanillaIceCream"},
- },
- }
- for _, moduleType := range []string{"android_app", "android_library"} {
- for _, test := range testCases {
- t.Run(moduleType+" "+test.name, func(t *testing.T) {
- platformApiProp := ""
- if test.platformApis {
- platformApiProp = "platform_apis: true,"
- }
- minSdkVersionProp := ""
- if test.minSdkVersionBp != "" {
- minSdkVersionProp = fmt.Sprintf(` min_sdk_version: "%s",`, test.minSdkVersionBp)
- }
- bp := fmt.Sprintf(`%s {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "%s",
- %s
- %s
- }`, moduleType, test.sdkVersion, platformApiProp, minSdkVersionProp)
- result := android.GroupFixturePreparers(
- prepareForJavaTest,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_sdk_version = &test.platformSdkInt
- variables.Platform_sdk_codename = &test.platformSdkCodename
- variables.Platform_version_active_codenames = test.activeCodenames
- variables.Platform_sdk_final = &test.platformSdkFinal
- }),
- FixtureWithPrebuiltApis(map[string][]string{
- "14": {"foo"},
- }),
- ).RunTestWithBp(t, bp)
- checkSdkVersion(t, result, test.expectedMinSdkVersion)
- })
- }
- }
- }
- func TestVendorAppSdkVersion(t *testing.T) {
- testCases := []struct {
- name string
- sdkVersion string
- platformSdkInt int
- platformSdkCodename string
- platformSdkFinal bool
- deviceCurrentApiLevelForVendorModules string
- expectedMinSdkVersion string
- }{
- {
- name: "current final SDK",
- sdkVersion: "current",
- platformSdkInt: 29,
- platformSdkCodename: "REL",
- platformSdkFinal: true,
- deviceCurrentApiLevelForVendorModules: "29",
- expectedMinSdkVersion: "29",
- },
- {
- name: "current final SDK",
- sdkVersion: "current",
- platformSdkInt: 29,
- platformSdkCodename: "REL",
- platformSdkFinal: true,
- deviceCurrentApiLevelForVendorModules: "28",
- expectedMinSdkVersion: "28",
- },
- {
- name: "current final SDK",
- sdkVersion: "current",
- platformSdkInt: 29,
- platformSdkCodename: "Q",
- platformSdkFinal: false,
- deviceCurrentApiLevelForVendorModules: "28",
- expectedMinSdkVersion: "28",
- },
- }
- for _, moduleType := range []string{"android_app", "android_library"} {
- for _, sdkKind := range []string{"", "system_"} {
- for _, test := range testCases {
- t.Run(moduleType+" "+test.name, func(t *testing.T) {
- bp := fmt.Sprintf(`%s {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "%s%s",
- vendor: true,
- }`, moduleType, sdkKind, test.sdkVersion)
- result := android.GroupFixturePreparers(
- prepareForJavaTest,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_sdk_version = &test.platformSdkInt
- variables.Platform_sdk_codename = &test.platformSdkCodename
- variables.Platform_sdk_final = &test.platformSdkFinal
- variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules
- variables.DeviceSystemSdkVersions = []string{"28", "29"}
- }),
- FixtureWithPrebuiltApis(map[string][]string{
- "28": {"foo"},
- "29": {"foo"},
- "current": {"foo"},
- }),
- ).RunTestWithBp(t, bp)
- checkSdkVersion(t, result, test.expectedMinSdkVersion)
- })
- }
- }
- }
- }
- func TestJNIABI(t *testing.T) {
- ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
- cc_library {
- name: "libjni",
- system_shared_libs: [],
- sdk_version: "current",
- stl: "none",
- }
- android_test {
- name: "test",
- sdk_version: "core_platform",
- jni_libs: ["libjni"],
- }
- android_test {
- name: "test_first",
- sdk_version: "core_platform",
- compile_multilib: "first",
- jni_libs: ["libjni"],
- }
- android_test {
- name: "test_both",
- sdk_version: "core_platform",
- compile_multilib: "both",
- jni_libs: ["libjni"],
- }
- android_test {
- name: "test_32",
- sdk_version: "core_platform",
- compile_multilib: "32",
- jni_libs: ["libjni"],
- }
- android_test {
- name: "test_64",
- sdk_version: "core_platform",
- compile_multilib: "64",
- jni_libs: ["libjni"],
- }
- `)
- testCases := []struct {
- name string
- abis []string
- }{
- {"test", []string{"arm64-v8a"}},
- {"test_first", []string{"arm64-v8a"}},
- {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
- {"test_32", []string{"armeabi-v7a"}},
- {"test_64", []string{"arm64-v8a"}},
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.Output(jniJarOutputPathString)
- var abis []string
- args := strings.Fields(jniLibZip.Args["jarArgs"])
- for i := 0; i < len(args); i++ {
- if args[i] == "-P" {
- abis = append(abis, filepath.Base(args[i+1]))
- i++
- }
- }
- if !reflect.DeepEqual(abis, test.abis) {
- t.Errorf("want abis %v, got %v", test.abis, abis)
- }
- })
- }
- }
- func TestAppSdkVersionByPartition(t *testing.T) {
- testJavaError(t, "sdk_version must have a value when the module is located at vendor or product", `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- vendor: true,
- platform_apis: true,
- }
- `)
- testJava(t, `
- android_app {
- name: "bar",
- srcs: ["b.java"],
- platform_apis: true,
- }
- `)
- for _, enforce := range []bool{true, false} {
- bp := `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- product_specific: true,
- platform_apis: true,
- }
- `
- errorHandler := android.FixtureExpectsNoErrors
- if enforce {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern("sdk_version must have a value when the module is located at vendor or product")
- }
- android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.EnforceProductPartitionInterface = proptools.BoolPtr(enforce)
- }),
- ).
- ExtendWithErrorHandler(errorHandler).
- RunTestWithBp(t, bp)
- }
- }
- func TestJNIPackaging(t *testing.T) {
- ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
- cc_library {
- name: "libjni",
- system_shared_libs: [],
- stl: "none",
- sdk_version: "current",
- }
- android_app {
- name: "app",
- jni_libs: ["libjni"],
- sdk_version: "current",
- }
- android_app {
- name: "app_noembed",
- jni_libs: ["libjni"],
- use_embedded_native_libs: false,
- sdk_version: "current",
- }
- android_app {
- name: "app_embed",
- jni_libs: ["libjni"],
- use_embedded_native_libs: true,
- sdk_version: "current",
- }
- android_test {
- name: "test",
- sdk_version: "current",
- jni_libs: ["libjni"],
- }
- android_test {
- name: "test_noembed",
- sdk_version: "current",
- jni_libs: ["libjni"],
- use_embedded_native_libs: false,
- }
- android_test_helper_app {
- name: "test_helper",
- sdk_version: "current",
- jni_libs: ["libjni"],
- }
- android_test_helper_app {
- name: "test_helper_noembed",
- sdk_version: "current",
- jni_libs: ["libjni"],
- use_embedded_native_libs: false,
- }
- `)
- testCases := []struct {
- name string
- packaged bool
- compressed bool
- }{
- {"app", false, false},
- {"app_noembed", false, false},
- {"app_embed", true, false},
- {"test", true, false},
- {"test_noembed", true, true},
- {"test_helper", true, false},
- {"test_helper_noembed", true, true},
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.MaybeOutput(jniJarOutputPathString)
- if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
- t.Errorf("expected jni packaged %v, got %v", w, g)
- }
- if jniLibZip.Rule != nil {
- if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
- t.Errorf("expected jni compressed %v, got %v", w, g)
- }
- if !strings.Contains(jniLibZip.Implicits[0].String(), "_sdk_") {
- t.Errorf("expected input %q to use sdk variant", jniLibZip.Implicits[0].String())
- }
- }
- })
- }
- }
- func TestJNISDK(t *testing.T) {
- ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
- cc_library {
- name: "libjni",
- system_shared_libs: [],
- stl: "none",
- sdk_version: "current",
- }
- android_test {
- name: "app_platform",
- jni_libs: ["libjni"],
- platform_apis: true,
- }
- android_test {
- name: "app_sdk",
- jni_libs: ["libjni"],
- sdk_version: "current",
- }
- android_test {
- name: "app_force_platform",
- jni_libs: ["libjni"],
- sdk_version: "current",
- jni_uses_platform_apis: true,
- }
- android_test {
- name: "app_force_sdk",
- jni_libs: ["libjni"],
- platform_apis: true,
- jni_uses_sdk_apis: true,
- }
- cc_library {
- name: "libvendorjni",
- system_shared_libs: [],
- stl: "none",
- vendor: true,
- }
- android_test {
- name: "app_vendor",
- jni_libs: ["libvendorjni"],
- sdk_version: "current",
- vendor: true,
- }
- `)
- testCases := []struct {
- name string
- sdkJNI bool
- vendorJNI bool
- }{
- {name: "app_platform"},
- {name: "app_sdk", sdkJNI: true},
- {name: "app_force_platform"},
- {name: "app_force_sdk", sdkJNI: true},
- {name: "app_vendor", vendorJNI: true},
- }
- platformJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared").
- Output("libjni.so").Output.String()
- sdkJNI := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").
- Output("libjni.so").Output.String()
- vendorJNI := ctx.ModuleForTests("libvendorjni", "android_arm64_armv8-a_shared").
- Output("libvendorjni.so").Output.String()
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.MaybeOutput(jniJarOutputPathString)
- if len(jniLibZip.Implicits) != 1 {
- t.Fatalf("expected exactly one jni library, got %q", jniLibZip.Implicits.Strings())
- }
- gotJNI := jniLibZip.Implicits[0].String()
- if test.sdkJNI {
- if gotJNI != sdkJNI {
- t.Errorf("expected SDK JNI library %q, got %q", sdkJNI, gotJNI)
- }
- } else if test.vendorJNI {
- if gotJNI != vendorJNI {
- t.Errorf("expected platform JNI library %q, got %q", vendorJNI, gotJNI)
- }
- } else {
- if gotJNI != platformJNI {
- t.Errorf("expected platform JNI library %q, got %q", platformJNI, gotJNI)
- }
- }
- })
- }
- t.Run("jni_uses_platform_apis_error", func(t *testing.T) {
- testJavaError(t, `jni_uses_platform_apis: can only be set for modules that set sdk_version`, `
- android_test {
- name: "app_platform",
- platform_apis: true,
- jni_uses_platform_apis: true,
- }
- `)
- })
- t.Run("jni_uses_sdk_apis_error", func(t *testing.T) {
- testJavaError(t, `jni_uses_sdk_apis: can only be set for modules that do not set sdk_version`, `
- android_test {
- name: "app_sdk",
- sdk_version: "current",
- jni_uses_sdk_apis: true,
- }
- `)
- })
- }
- func TestCertificates(t *testing.T) {
- testCases := []struct {
- name string
- bp string
- allowMissingDependencies bool
- certificateOverride string
- expectedCertSigningFlags string
- expectedCertificate string
- }{
- {
- name: "default",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- certificateOverride: "",
- expectedCertSigningFlags: "",
- expectedCertificate: "build/make/target/product/security/testkey",
- },
- {
- name: "module certificate property",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: ":new_certificate",
- sdk_version: "current",
- }
- android_app_certificate {
- name: "new_certificate",
- certificate: "cert/new_cert",
- }
- `,
- certificateOverride: "",
- expectedCertSigningFlags: "",
- expectedCertificate: "cert/new_cert",
- },
- {
- name: "path certificate property",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: "expiredkey",
- sdk_version: "current",
- }
- `,
- certificateOverride: "",
- expectedCertSigningFlags: "",
- expectedCertificate: "build/make/target/product/security/expiredkey",
- },
- {
- name: "certificate overrides",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: "expiredkey",
- sdk_version: "current",
- }
- android_app_certificate {
- name: "new_certificate",
- certificate: "cert/new_cert",
- }
- `,
- certificateOverride: "foo:new_certificate",
- expectedCertSigningFlags: "",
- expectedCertificate: "cert/new_cert",
- },
- {
- name: "certificate signing flags",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: ":new_certificate",
- lineage: "lineage.bin",
- rotationMinSdkVersion: "32",
- sdk_version: "current",
- }
- android_app_certificate {
- name: "new_certificate",
- certificate: "cert/new_cert",
- }
- `,
- certificateOverride: "",
- expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
- expectedCertificate: "cert/new_cert",
- },
- {
- name: "cert signing flags from filegroup",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: ":new_certificate",
- lineage: ":lineage_bin",
- rotationMinSdkVersion: "32",
- sdk_version: "current",
- }
- android_app_certificate {
- name: "new_certificate",
- certificate: "cert/new_cert",
- }
- filegroup {
- name: "lineage_bin",
- srcs: ["lineage.bin"],
- }
- `,
- certificateOverride: "",
- expectedCertSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
- expectedCertificate: "cert/new_cert",
- },
- {
- name: "missing with AllowMissingDependencies",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: ":new_certificate",
- sdk_version: "current",
- }
- `,
- expectedCertificate: "out/soong/.intermediates/foo/android_common/missing",
- allowMissingDependencies: true,
- },
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- if test.certificateOverride != "" {
- variables.CertificateOverrides = []string{test.certificateOverride}
- }
- if test.allowMissingDependencies {
- variables.Allow_missing_dependencies = proptools.BoolPtr(true)
- }
- }),
- android.FixtureModifyContext(func(ctx *android.TestContext) {
- ctx.SetAllowMissingDependencies(test.allowMissingDependencies)
- }),
- ).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
- certificate := foo.Module().(*AndroidApp).certificate
- android.AssertPathRelativeToTopEquals(t, "certificates key", test.expectedCertificate+".pk8", certificate.Key)
- // The sign_target_files_apks and check_target_files_signatures
- // tools require that certificates have a .x509.pem extension.
- android.AssertPathRelativeToTopEquals(t, "certificates pem", test.expectedCertificate+".x509.pem", certificate.Pem)
- signapk := foo.Output("foo.apk")
- if signapk.Rule != android.ErrorRule {
- signCertificateFlags := signapk.Args["certificates"]
- expectedFlags := certificate.Pem.String() + " " + certificate.Key.String()
- android.AssertStringEquals(t, "certificates flags", expectedFlags, signCertificateFlags)
- certSigningFlags := signapk.Args["flags"]
- android.AssertStringEquals(t, "cert signing flags", test.expectedCertSigningFlags, certSigningFlags)
- }
- })
- }
- }
- func TestRequestV4SigningFlag(t *testing.T) {
- testCases := []struct {
- name string
- bp string
- expected string
- }{
- {
- name: "default",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- expected: "",
- },
- {
- name: "default",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- v4_signature: false,
- }
- `,
- expected: "",
- },
- {
- name: "module certificate property",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- v4_signature: true,
- }
- `,
- expected: "--enable-v4",
- },
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- ).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
- signapk := foo.Output("foo.apk")
- signFlags := signapk.Args["flags"]
- android.AssertStringEquals(t, "signing flags", test.expected, signFlags)
- })
- }
- }
- func TestPackageNameOverride(t *testing.T) {
- testCases := []struct {
- name string
- bp string
- packageNameOverride string
- expected []string
- }{
- {
- name: "default",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- packageNameOverride: "",
- expected: []string{
- "out/soong/.intermediates/foo/android_common/foo.apk",
- "out/soong/target/product/test_device/system/app/foo/foo.apk",
- },
- },
- {
- name: "overridden via PRODUCT_PACKAGE_NAME_OVERRIDES",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- packageNameOverride: "foo:bar",
- expected: []string{
- // The package apk should be still be the original name for test dependencies.
- "out/soong/.intermediates/foo/android_common/bar.apk",
- "out/soong/target/product/test_device/system/app/bar/bar.apk",
- },
- },
- {
- name: "overridden via stem",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- stem: "bar",
- }
- `,
- packageNameOverride: "",
- expected: []string{
- "out/soong/.intermediates/foo/android_common/bar.apk",
- "out/soong/target/product/test_device/system/app/bar/bar.apk",
- },
- },
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- if test.packageNameOverride != "" {
- variables.PackageNameOverrides = []string{test.packageNameOverride}
- }
- }),
- ).RunTestWithBp(t, test.bp)
- foo := result.ModuleForTests("foo", "android_common")
- outSoongDir := result.Config.SoongOutDir()
- outputs := foo.AllOutputs()
- outputMap := make(map[string]bool)
- for _, o := range outputs {
- outputMap[android.StringPathRelativeToTop(outSoongDir, o)] = true
- }
- for _, e := range test.expected {
- if _, exist := outputMap[e]; !exist {
- t.Errorf("Can't find %q in output files.\nAll outputs:%v", e, outputs)
- }
- }
- })
- }
- }
- func TestInstrumentationTargetOverridden(t *testing.T) {
- bp := `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- android_test {
- name: "bar",
- instrumentation_for: "foo",
- sdk_version: "current",
- }
- `
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.ManifestPackageNameOverrides = []string{"foo:org.dandroid.bp"}
- }),
- ).RunTestWithBp(t, bp)
- bar := result.ModuleForTests("bar", "android_common")
- res := bar.Output("package-res.apk")
- aapt2Flags := res.Args["flags"]
- e := "--rename-instrumentation-target-package org.dandroid.bp"
- if !strings.Contains(aapt2Flags, e) {
- t.Errorf("target package renaming flag, %q is missing in aapt2 link flags, %q", e, aapt2Flags)
- }
- }
- func TestOverrideAndroidApp(t *testing.T) {
- result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
- t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: "expiredkey",
- overrides: ["qux"],
- sdk_version: "current",
- }
- override_android_app {
- name: "bar",
- base: "foo",
- certificate: ":new_certificate",
- lineage: "lineage.bin",
- rotationMinSdkVersion: "32",
- logging_parent: "bah",
- }
- android_app_certificate {
- name: "new_certificate",
- certificate: "cert/new_cert",
- }
- override_android_app {
- name: "baz",
- base: "foo",
- package_name: "org.dandroid.bp",
- }
- override_android_app {
- name: "baz_no_rename_resources",
- base: "foo",
- package_name: "org.dandroid.bp",
- rename_resources_package: false,
- }
- android_app {
- name: "foo_no_rename_resources",
- srcs: ["a.java"],
- certificate: "expiredkey",
- overrides: ["qux"],
- rename_resources_package: false,
- sdk_version: "current",
- }
- override_android_app {
- name: "baz_base_no_rename_resources",
- base: "foo_no_rename_resources",
- package_name: "org.dandroid.bp",
- }
- override_android_app {
- name: "baz_override_base_rename_resources",
- base: "foo_no_rename_resources",
- package_name: "org.dandroid.bp",
- rename_resources_package: true,
- }
- `)
- expectedVariants := []struct {
- name string
- moduleName string
- variantName string
- apkName string
- apkPath string
- certFlag string
- certSigningFlags string
- overrides []string
- packageFlag string
- renameResources bool
- logging_parent string
- }{
- {
- name: "foo",
- moduleName: "foo",
- variantName: "android_common",
- apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk",
- certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- certSigningFlags: "",
- overrides: []string{"qux"},
- packageFlag: "",
- renameResources: false,
- logging_parent: "",
- },
- {
- name: "foo",
- moduleName: "bar",
- variantName: "android_common_bar",
- apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk",
- certFlag: "cert/new_cert.x509.pem cert/new_cert.pk8",
- certSigningFlags: "--lineage lineage.bin --rotation-min-sdk-version 32",
- overrides: []string{"qux", "foo"},
- packageFlag: "",
- renameResources: false,
- logging_parent: "bah",
- },
- {
- name: "foo",
- moduleName: "baz",
- variantName: "android_common_baz",
- apkPath: "out/soong/target/product/test_device/system/app/baz/baz.apk",
- certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- certSigningFlags: "",
- overrides: []string{"qux", "foo"},
- packageFlag: "org.dandroid.bp",
- renameResources: true,
- logging_parent: "",
- },
- {
- name: "foo",
- moduleName: "baz_no_rename_resources",
- variantName: "android_common_baz_no_rename_resources",
- apkPath: "out/soong/target/product/test_device/system/app/baz_no_rename_resources/baz_no_rename_resources.apk",
- certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- certSigningFlags: "",
- overrides: []string{"qux", "foo"},
- packageFlag: "org.dandroid.bp",
- renameResources: false,
- logging_parent: "",
- },
- {
- name: "foo_no_rename_resources",
- moduleName: "baz_base_no_rename_resources",
- variantName: "android_common_baz_base_no_rename_resources",
- apkPath: "out/soong/target/product/test_device/system/app/baz_base_no_rename_resources/baz_base_no_rename_resources.apk",
- certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- certSigningFlags: "",
- overrides: []string{"qux", "foo_no_rename_resources"},
- packageFlag: "org.dandroid.bp",
- renameResources: false,
- logging_parent: "",
- },
- {
- name: "foo_no_rename_resources",
- moduleName: "baz_override_base_rename_resources",
- variantName: "android_common_baz_override_base_rename_resources",
- apkPath: "out/soong/target/product/test_device/system/app/baz_override_base_rename_resources/baz_override_base_rename_resources.apk",
- certFlag: "build/make/target/product/security/expiredkey.x509.pem build/make/target/product/security/expiredkey.pk8",
- certSigningFlags: "",
- overrides: []string{"qux", "foo_no_rename_resources"},
- packageFlag: "org.dandroid.bp",
- renameResources: true,
- logging_parent: "",
- },
- }
- for _, expected := range expectedVariants {
- variant := result.ModuleForTests(expected.name, expected.variantName)
- // Check the final apk name
- variant.Output(expected.apkPath)
- // Check the certificate paths
- signapk := variant.Output(expected.moduleName + ".apk")
- certFlag := signapk.Args["certificates"]
- android.AssertStringEquals(t, "certificates flags", expected.certFlag, certFlag)
- // Check the cert signing flags
- certSigningFlags := signapk.Args["flags"]
- android.AssertStringEquals(t, "cert signing flags", expected.certSigningFlags, certSigningFlags)
- // Check if the overrides field values are correctly aggregated.
- mod := variant.Module().(*AndroidApp)
- android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
- // Test Overridable property: Logging_parent
- logging_parent := mod.aapt.LoggingParent
- android.AssertStringEquals(t, "overrides property value for logging parent", expected.logging_parent, logging_parent)
- // Check the package renaming flag, if exists.
- res := variant.Output("package-res.apk")
- aapt2Flags := res.Args["flags"]
- checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
- expectedPackage := expected.packageFlag
- if !expected.renameResources {
- expectedPackage = ""
- }
- checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expectedPackage)
- }
- }
- func TestOverrideAndroidAppOverrides(t *testing.T) {
- ctx, _ := testJava(
- t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- overrides: ["qux"]
- }
- android_app {
- name: "bar",
- srcs: ["b.java"],
- sdk_version: "current",
- overrides: ["foo"]
- }
- override_android_app {
- name: "foo_override",
- base: "foo",
- overrides: ["bar"]
- }
- `)
- expectedVariants := []struct {
- name string
- moduleName string
- variantName string
- overrides []string
- }{
- {
- name: "foo",
- moduleName: "foo",
- variantName: "android_common",
- overrides: []string{"qux"},
- },
- {
- name: "bar",
- moduleName: "bar",
- variantName: "android_common",
- overrides: []string{"foo"},
- },
- {
- name: "foo",
- moduleName: "foo_override",
- variantName: "android_common_foo_override",
- overrides: []string{"bar", "foo"},
- },
- }
- for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests(expected.name, expected.variantName)
- // Check if the overrides field values are correctly aggregated.
- mod := variant.Module().(*AndroidApp)
- android.AssertDeepEquals(t, "overrides property", expected.overrides, mod.overridableAppProperties.Overrides)
- }
- }
- func TestOverrideAndroidAppWithPrebuilt(t *testing.T) {
- result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
- t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- override_android_app {
- name: "bar",
- base: "foo",
- }
- android_app_import {
- name: "bar",
- prefer: true,
- apk: "bar.apk",
- presigned: true,
- }
- `)
- // An app that has an override that also has a prebuilt should not be hidden.
- foo := result.ModuleForTests("foo", "android_common")
- if foo.Module().IsHideFromMake() {
- t.Errorf("expected foo to have HideFromMake false")
- }
- // An override that also has a prebuilt should be hidden.
- barOverride := result.ModuleForTests("foo", "android_common_bar")
- if !barOverride.Module().IsHideFromMake() {
- t.Errorf("expected bar override variant of foo to have HideFromMake true")
- }
- }
- func TestOverrideAndroidAppStem(t *testing.T) {
- ctx, _ := testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- override_android_app {
- name: "bar",
- base: "foo",
- }
- override_android_app {
- name: "baz",
- base: "foo",
- stem: "baz_stem",
- }
- android_app {
- name: "foo2",
- srcs: ["a.java"],
- sdk_version: "current",
- stem: "foo2_stem",
- }
- override_android_app {
- name: "bar2",
- base: "foo2",
- }
- override_android_app {
- name: "baz2",
- base: "foo2",
- stem: "baz2_stem",
- }
- `)
- for _, expected := range []struct {
- moduleName string
- variantName string
- apkPath string
- }{
- {
- moduleName: "foo",
- variantName: "android_common",
- apkPath: "out/soong/target/product/test_device/system/app/foo/foo.apk",
- },
- {
- moduleName: "foo",
- variantName: "android_common_bar",
- apkPath: "out/soong/target/product/test_device/system/app/bar/bar.apk",
- },
- {
- moduleName: "foo",
- variantName: "android_common_baz",
- apkPath: "out/soong/target/product/test_device/system/app/baz_stem/baz_stem.apk",
- },
- {
- moduleName: "foo2",
- variantName: "android_common",
- apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
- },
- {
- moduleName: "foo2",
- variantName: "android_common_bar2",
- // Note that this may cause the duplicate output error.
- apkPath: "out/soong/target/product/test_device/system/app/foo2_stem/foo2_stem.apk",
- },
- {
- moduleName: "foo2",
- variantName: "android_common_baz2",
- apkPath: "out/soong/target/product/test_device/system/app/baz2_stem/baz2_stem.apk",
- },
- } {
- variant := ctx.ModuleForTests(expected.moduleName, expected.variantName)
- variant.Output(expected.apkPath)
- }
- }
- func TestOverrideAndroidAppDependency(t *testing.T) {
- ctx, _ := testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- override_android_app {
- name: "bar",
- base: "foo",
- package_name: "org.dandroid.bp",
- }
- android_test {
- name: "baz",
- srcs: ["b.java"],
- instrumentation_for: "foo",
- }
- android_test {
- name: "qux",
- srcs: ["b.java"],
- instrumentation_for: "bar",
- }
- `)
- // Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
- javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
- fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
- if !strings.Contains(javac.Args["classpath"], fooTurbine) {
- t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
- }
- // Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
- javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
- barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
- if !strings.Contains(javac.Args["classpath"], barTurbine) {
- t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
- }
- }
- func TestOverrideAndroidTest(t *testing.T) {
- ctx, _ := testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- package_name: "com.android.foo",
- sdk_version: "current",
- }
- override_android_app {
- name: "bar",
- base: "foo",
- package_name: "com.android.bar",
- }
- android_test {
- name: "foo_test",
- srcs: ["b.java"],
- instrumentation_for: "foo",
- }
- override_android_test {
- name: "bar_test",
- base: "foo_test",
- package_name: "com.android.bar.test",
- instrumentation_for: "bar",
- instrumentation_target_package: "com.android.bar",
- }
- `)
- expectedVariants := []struct {
- moduleName string
- variantName string
- apkPath string
- overrides []string
- targetVariant string
- packageFlag string
- targetPackageFlag string
- }{
- {
- variantName: "android_common",
- apkPath: "/target/product/test_device/testcases/foo_test/arm64/foo_test.apk",
- overrides: nil,
- targetVariant: "android_common",
- packageFlag: "",
- targetPackageFlag: "",
- },
- {
- variantName: "android_common_bar_test",
- apkPath: "/target/product/test_device/testcases/bar_test/arm64/bar_test.apk",
- overrides: []string{"foo_test"},
- targetVariant: "android_common_bar",
- packageFlag: "com.android.bar.test",
- targetPackageFlag: "com.android.bar",
- },
- }
- for _, expected := range expectedVariants {
- variant := ctx.ModuleForTests("foo_test", expected.variantName)
- // Check the final apk name
- variant.Output("out/soong" + expected.apkPath)
- // Check if the overrides field values are correctly aggregated.
- mod := variant.Module().(*AndroidTest)
- if !reflect.DeepEqual(expected.overrides, mod.overridableAppProperties.Overrides) {
- t.Errorf("Incorrect overrides property value, expected: %q, got: %q",
- expected.overrides, mod.overridableAppProperties.Overrides)
- }
- // Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
- javac := variant.Rule("javac")
- turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
- if !strings.Contains(javac.Args["classpath"], turbine) {
- t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
- }
- // Check aapt2 flags.
- res := variant.Output("package-res.apk")
- aapt2Flags := res.Args["flags"]
- checkAapt2LinkFlag(t, aapt2Flags, "rename-manifest-package", expected.packageFlag)
- checkAapt2LinkFlag(t, aapt2Flags, "rename-resources-package", expected.packageFlag)
- checkAapt2LinkFlag(t, aapt2Flags, "rename-instrumentation-target-package", expected.targetPackageFlag)
- }
- }
- func TestAndroidTest_FixTestConfig(t *testing.T) {
- ctx, _ := testJava(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- package_name: "com.android.foo",
- sdk_version: "current",
- }
- android_test {
- name: "foo_test",
- srcs: ["b.java"],
- instrumentation_for: "foo",
- }
- android_test {
- name: "bar_test",
- srcs: ["b.java"],
- package_name: "com.android.bar.test",
- instrumentation_for: "foo",
- mainline_package_name: "com.android.bar",
- }
- override_android_test {
- name: "baz_test",
- base: "foo_test",
- package_name: "com.android.baz.test",
- mainline_package_name: "com.android.baz",
- }
- `)
- testCases := []struct {
- moduleName string
- variantName string
- expectedFlags []string
- }{
- {
- moduleName: "foo_test",
- variantName: "android_common",
- },
- {
- moduleName: "bar_test",
- variantName: "android_common",
- expectedFlags: []string{
- "--manifest out/soong/.intermediates/bar_test/android_common/manifest_fixer/AndroidManifest.xml",
- "--package-name com.android.bar.test",
- "--mainline-package-name com.android.bar",
- },
- },
- {
- moduleName: "foo_test",
- variantName: "android_common_baz_test",
- expectedFlags: []string{
- "--manifest out/soong/.intermediates/foo_test/android_common_baz_test/manifest_fixer/AndroidManifest.xml",
- "--package-name com.android.baz.test",
- "--test-file-name baz_test.apk",
- "out/soong/.intermediates/foo_test/android_common_baz_test/test_config_fixer/AndroidTest.xml",
- "--mainline-package-name com.android.baz",
- },
- },
- }
- for _, test := range testCases {
- variant := ctx.ModuleForTests(test.moduleName, test.variantName)
- params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
- if len(test.expectedFlags) > 0 {
- if params.Rule == nil {
- t.Errorf("test_config_fixer was expected to run, but didn't")
- } else {
- for _, flag := range test.expectedFlags {
- if !strings.Contains(params.RuleParams.Command, flag) {
- t.Errorf("Flag %q was not found in command: %q", flag, params.RuleParams.Command)
- }
- }
- }
- } else {
- if params.Rule != nil {
- t.Errorf("test_config_fixer was not expected to run, but did: %q", params.RuleParams.Command)
- }
- }
- }
- }
- func TestInstrumentationTargetPrebuilt(t *testing.T) {
- bp := `
- android_app_import {
- name: "foo",
- apk: "foo.apk",
- presigned: true,
- }
- android_test {
- name: "bar",
- srcs: ["a.java"],
- instrumentation_for: "foo",
- sdk_version: "current",
- }
- `
- android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- ).ExtendWithErrorHandler(
- android.FixtureExpectsAtLeastOneErrorMatchingPattern(
- "instrumentation_for: dependency \"foo\" of type \"android_app_import\" does not provide JavaInfo so is unsuitable for use with this property")).
- RunTestWithBp(t, bp)
- }
- func TestStl(t *testing.T) {
- ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
- cc_library {
- name: "libjni",
- sdk_version: "current",
- stl: "c++_shared",
- }
- android_test {
- name: "stl",
- jni_libs: ["libjni"],
- compile_multilib: "both",
- sdk_version: "current",
- stl: "c++_shared",
- }
- android_test {
- name: "system",
- jni_libs: ["libjni"],
- compile_multilib: "both",
- sdk_version: "current",
- }
- `)
- testCases := []struct {
- name string
- jnis []string
- }{
- {"stl",
- []string{
- "libjni.so",
- "libc++_shared.so",
- },
- },
- {"system",
- []string{
- "libjni.so",
- },
- },
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.Output(jniJarOutputPathString)
- var jnis []string
- args := strings.Fields(jniLibZip.Args["jarArgs"])
- for i := 0; i < len(args); i++ {
- if args[i] == "-f" {
- jnis = append(jnis, args[i+1])
- i += 1
- }
- }
- jnisJoined := strings.Join(jnis, " ")
- for _, jni := range test.jnis {
- if !strings.Contains(jnisJoined, jni) {
- t.Errorf("missing jni %q in %q", jni, jnis)
- }
- }
- })
- }
- }
- func TestUsesLibraries(t *testing.T) {
- bp := `
- java_sdk_library {
- name: "foo",
- srcs: ["a.java"],
- api_packages: ["foo"],
- sdk_version: "current",
- }
- java_sdk_library {
- name: "qux",
- srcs: ["a.java"],
- api_packages: ["qux"],
- sdk_version: "current",
- }
- java_sdk_library {
- name: "quuz",
- srcs: ["a.java"],
- api_packages: ["quuz"],
- sdk_version: "current",
- }
- java_sdk_library {
- name: "fred",
- srcs: ["a.java"],
- api_packages: ["fred"],
- sdk_version: "current",
- }
- java_sdk_library {
- name: "bar",
- srcs: ["a.java"],
- api_packages: ["bar"],
- sdk_version: "current",
- }
- java_sdk_library {
- name: "runtime-library",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- java_library {
- name: "static-runtime-helper",
- srcs: ["a.java"],
- libs: ["runtime-library"],
- sdk_version: "current",
- }
- java_library {
- name: "runtime-required-x",
- srcs: ["a.java"],
- installable: true,
- sdk_version: "current",
- }
- java_library {
- name: "runtime-optional-x",
- srcs: ["a.java"],
- installable: true,
- sdk_version: "current",
- }
- android_library {
- name: "static-x",
- uses_libs: ["runtime-required-x"],
- optional_uses_libs: ["runtime-optional-x"],
- sdk_version: "current",
- }
- java_library {
- name: "runtime-required-y",
- srcs: ["a.java"],
- installable: true,
- sdk_version: "current",
- }
- java_library {
- name: "runtime-optional-y",
- srcs: ["a.java"],
- installable: true,
- sdk_version: "current",
- }
- java_library {
- name: "static-y",
- srcs: ["a.java"],
- uses_libs: ["runtime-required-y"],
- optional_uses_libs: ["runtime-optional-y"],
- sdk_version: "current",
- }
- // A library that has to use "provides_uses_lib", because:
- // - it is not an SDK library
- // - its library name is different from its module name
- java_library {
- name: "non-sdk-lib",
- provides_uses_lib: "com.non.sdk.lib",
- installable: true,
- srcs: ["a.java"],
- }
- android_app {
- name: "app",
- srcs: ["a.java"],
- libs: [
- "qux",
- "quuz.stubs"
- ],
- static_libs: [
- "static-runtime-helper",
- // statically linked component libraries should not pull their SDK libraries,
- // so "fred" should not be added to class loader context
- "fred.stubs",
- "static-x",
- "static-y",
- ],
- uses_libs: [
- "foo",
- "non-sdk-lib"
- ],
- sdk_version: "current",
- optional_uses_libs: [
- "bar",
- "baz",
- ],
- }
- android_app_import {
- name: "prebuilt",
- apk: "prebuilts/apk/app.apk",
- certificate: "platform",
- uses_libs: [
- "foo",
- "non-sdk-lib",
- "android.test.runner"
- ],
- optional_uses_libs: [
- "bar",
- "baz",
- ],
- }
- `
- result := android.GroupFixturePreparers(
- prepareForJavaTest,
- PrepareForTestWithJavaSdkLibraryFiles,
- FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"),
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"}
- }),
- ).RunTestWithBp(t, bp)
- app := result.ModuleForTests("app", "android_common")
- prebuilt := result.ModuleForTests("prebuilt", "android_common")
- // Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
- // These also include explicit `uses_libs`/`optional_uses_libs` entries, as they may be
- // propagated from dependencies.
- actualManifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- expectManifestFixerArgs := `--extract-native-libs=true ` +
- `--uses-library qux ` +
- `--uses-library quuz ` +
- `--uses-library foo ` +
- `--uses-library com.non.sdk.lib ` +
- `--uses-library runtime-library ` +
- `--uses-library runtime-required-x ` +
- `--uses-library runtime-required-y ` +
- `--optional-uses-library bar ` +
- `--optional-uses-library runtime-optional-x ` +
- `--optional-uses-library runtime-optional-y`
- android.AssertStringDoesContain(t, "manifest_fixer args", actualManifestFixerArgs, expectManifestFixerArgs)
- // Test that all libraries are verified (library order matters).
- verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command
- verifyArgs := `--uses-library foo ` +
- `--uses-library com.non.sdk.lib ` +
- `--uses-library qux ` +
- `--uses-library quuz ` +
- `--uses-library runtime-library ` +
- `--uses-library runtime-required-x ` +
- `--uses-library runtime-required-y ` +
- `--optional-uses-library bar ` +
- `--optional-uses-library baz ` +
- `--optional-uses-library runtime-optional-x ` +
- `--optional-uses-library runtime-optional-y `
- android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs)
- // Test that all libraries are verified for an APK (library order matters).
- verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command
- verifyApkArgs := `--uses-library foo ` +
- `--uses-library com.non.sdk.lib ` +
- `--uses-library android.test.runner ` +
- `--optional-uses-library bar ` +
- `--optional-uses-library baz `
- android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs)
- // Test that necessary args are passed for constructing CLC in Ninja phase.
- cmd := app.Rule("dexpreopt").RuleParams.Command
- android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=")
- android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd,
- "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/product_packages.txt")
- }
- func TestDexpreoptBcp(t *testing.T) {
- bp := `
- java_sdk_library {
- name: "foo",
- srcs: ["a.java"],
- api_packages: ["foo"],
- sdk_version: "current",
- }
- java_sdk_library {
- name: "bar",
- srcs: ["a.java"],
- api_packages: ["bar"],
- permitted_packages: ["bar"],
- sdk_version: "current",
- }
- android_app {
- name: "app",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `
- testCases := []struct {
- name string
- with bool
- expect string
- }{
- {
- name: "with updatable bcp",
- with: true,
- expect: "/system/framework/foo.jar:/system/framework/bar.jar",
- },
- {
- name: "without updatable bcp",
- with: false,
- expect: "/system/framework/foo.jar",
- },
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- result := android.GroupFixturePreparers(
- prepareForJavaTest,
- PrepareForTestWithJavaSdkLibraryFiles,
- FixtureWithLastReleaseApis("runtime-library", "foo", "bar"),
- dexpreopt.FixtureSetBootJars("platform:foo"),
- dexpreopt.FixtureSetApexBootJars("platform:bar"),
- dexpreopt.FixtureSetPreoptWithUpdatableBcp(test.with),
- ).RunTestWithBp(t, bp)
- app := result.ModuleForTests("app", "android_common")
- cmd := app.Rule("dexpreopt").RuleParams.Command
- bcp := " -Xbootclasspath-locations:" + test.expect + " " // space at the end matters
- android.AssertStringDoesContain(t, "dexpreopt app bcp", cmd, bcp)
- })
- }
- }
- func TestCodelessApp(t *testing.T) {
- testCases := []struct {
- name string
- bp string
- noCode bool
- }{
- {
- name: "normal",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- noCode: false,
- },
- {
- name: "app without sources",
- bp: `
- android_app {
- name: "foo",
- sdk_version: "current",
- }
- `,
- noCode: true,
- },
- {
- name: "app with libraries",
- bp: `
- android_app {
- name: "foo",
- static_libs: ["lib"],
- sdk_version: "current",
- }
- java_library {
- name: "lib",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- noCode: false,
- },
- {
- name: "app with sourceless libraries",
- bp: `
- android_app {
- name: "foo",
- static_libs: ["lib"],
- sdk_version: "current",
- }
- java_library {
- name: "lib",
- sdk_version: "current",
- }
- `,
- // TODO(jungjw): this should probably be true
- noCode: false,
- },
- }
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- ctx := testApp(t, test.bp)
- foo := ctx.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- if strings.Contains(manifestFixerArgs, "--has-no-code") != test.noCode {
- t.Errorf("unexpected manifest_fixer args: %q", manifestFixerArgs)
- }
- })
- }
- }
- func TestUncompressDex(t *testing.T) {
- testCases := []struct {
- name string
- bp string
- uncompressedPlatform bool
- uncompressedUnbundled bool
- }{
- {
- name: "normal",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- uncompressedPlatform: true,
- uncompressedUnbundled: false,
- },
- {
- name: "use_embedded_dex",
- bp: `
- android_app {
- name: "foo",
- use_embedded_dex: true,
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- uncompressedPlatform: true,
- uncompressedUnbundled: true,
- },
- {
- name: "privileged",
- bp: `
- android_app {
- name: "foo",
- privileged: true,
- srcs: ["a.java"],
- sdk_version: "current",
- }
- `,
- uncompressedPlatform: true,
- uncompressedUnbundled: true,
- },
- {
- name: "normal_uncompress_dex_true",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- uncompress_dex: true,
- }
- `,
- uncompressedPlatform: true,
- uncompressedUnbundled: true,
- },
- {
- name: "normal_uncompress_dex_false",
- bp: `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- sdk_version: "current",
- uncompress_dex: false,
- }
- `,
- uncompressedPlatform: false,
- uncompressedUnbundled: false,
- },
- }
- test := func(t *testing.T, bp string, want bool, unbundled bool) {
- t.Helper()
- result := android.GroupFixturePreparers(
- prepareForJavaTest,
- PrepareForTestWithPrebuiltsOfCurrentApi,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- if unbundled {
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
- }
- }),
- ).RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
- dex := foo.Rule("r8")
- uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0")
- aligned := foo.MaybeRule("zipalign").Rule != nil
- android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar)
- android.AssertBoolEquals(t, "aligne", want, aligned)
- }
- for _, tt := range testCases {
- t.Run(tt.name, func(t *testing.T) {
- t.Run("platform", func(t *testing.T) {
- test(t, tt.bp, tt.uncompressedPlatform, false)
- })
- t.Run("unbundled", func(t *testing.T) {
- test(t, tt.bp, tt.uncompressedUnbundled, true)
- })
- })
- }
- }
- func checkAapt2LinkFlag(t *testing.T, aapt2Flags, flagName, expectedValue string) {
- if expectedValue != "" {
- expectedFlag := "--" + flagName + " " + expectedValue
- if !strings.Contains(aapt2Flags, expectedFlag) {
- t.Errorf("%q is missing in aapt2 link flags, %q", expectedFlag, aapt2Flags)
- }
- } else {
- unexpectedFlag := "--" + flagName
- if strings.Contains(aapt2Flags, unexpectedFlag) {
- t.Errorf("unexpected flag, %q is found in aapt2 link flags, %q", unexpectedFlag, aapt2Flags)
- }
- }
- }
- func TestExportedProguardFlagFiles(t *testing.T) {
- ctx, _ := testJava(t, `
- android_app {
- name: "foo",
- sdk_version: "current",
- static_libs: ["lib1"],
- }
- android_library {
- name: "lib1",
- sdk_version: "current",
- optimize: {
- proguard_flags_files: ["lib1proguard.cfg"],
- }
- }
- `)
- m := ctx.ModuleForTests("foo", "android_common")
- hasLib1Proguard := false
- for _, s := range m.Rule("java.r8").Implicits.Strings() {
- if s == "lib1proguard.cfg" {
- hasLib1Proguard = true
- break
- }
- }
- if !hasLib1Proguard {
- t.Errorf("App does not use library proguard config")
- }
- }
- func TestTargetSdkVersionManifestFixer(t *testing.T) {
- platform_sdk_codename := "Tiramisu"
- platform_sdk_version := 33
- testCases := []struct {
- name string
- targetSdkVersionInBp string
- targetSdkVersionExpected string
- unbundledBuild bool
- platformSdkFinal bool
- }{
- {
- name: "Non-Unbundled build: Android.bp has targetSdkVersion",
- targetSdkVersionInBp: "30",
- targetSdkVersionExpected: "30",
- unbundledBuild: false,
- },
- {
- name: "Unbundled build: Android.bp has targetSdkVersion",
- targetSdkVersionInBp: "30",
- targetSdkVersionExpected: "30",
- unbundledBuild: true,
- },
- {
- name: "Non-Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
- targetSdkVersionInBp: platform_sdk_codename,
- targetSdkVersionExpected: platform_sdk_codename,
- unbundledBuild: false,
- },
- {
- name: "Unbundled build: Android.bp has targetSdkVersion equal to platform_sdk_codename",
- targetSdkVersionInBp: platform_sdk_codename,
- targetSdkVersionExpected: "10000",
- unbundledBuild: true,
- },
- {
- name: "Non-Unbundled build: Android.bp has no targetSdkVersion",
- targetSdkVersionExpected: platform_sdk_codename,
- unbundledBuild: false,
- },
- {
- name: "Unbundled build: Android.bp has no targetSdkVersion",
- targetSdkVersionExpected: "10000",
- unbundledBuild: true,
- },
- {
- name: "Bundled build in REL branches",
- targetSdkVersionExpected: "33",
- unbundledBuild: false,
- platformSdkFinal: true,
- },
- }
- for _, testCase := range testCases {
- targetSdkVersionTemplate := ""
- if testCase.targetSdkVersionInBp != "" {
- targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, testCase.targetSdkVersionInBp)
- }
- bp := fmt.Sprintf(`
- android_app {
- name: "foo",
- sdk_version: "current",
- %s
- }
- `, targetSdkVersionTemplate)
- fixture := android.GroupFixturePreparers(
- prepareForJavaTest,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- if testCase.platformSdkFinal {
- variables.Platform_sdk_final = proptools.BoolPtr(true)
- }
- // explicitly set platform_sdk_codename to make the test deterministic
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_version_active_codenames = []string{platform_sdk_codename}
- // create a non-empty list if unbundledBuild==true
- if testCase.unbundledBuild {
- variables.Unbundled_build_apps = []string{"apex_a", "apex_b"}
- }
- }),
- )
- result := fixture.RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
- }
- func TestDefaultAppTargetSdkVersionForUpdatableModules(t *testing.T) {
- platform_sdk_codename := "Tiramisu"
- platform_sdk_version := 33
- testCases := []struct {
- name string
- platform_sdk_final bool
- targetSdkVersionInBp *string
- targetSdkVersionExpected *string
- updatable bool
- }{
- {
- name: "Non-Updatable Module: Android.bp has older targetSdkVersion",
- targetSdkVersionInBp: proptools.StringPtr("29"),
- targetSdkVersionExpected: proptools.StringPtr("29"),
- updatable: false,
- },
- {
- name: "Updatable Module: Android.bp has older targetSdkVersion",
- targetSdkVersionInBp: proptools.StringPtr("30"),
- targetSdkVersionExpected: proptools.StringPtr("30"),
- updatable: true,
- },
- {
- name: "Updatable Module: Android.bp has no targetSdkVersion",
- targetSdkVersionExpected: proptools.StringPtr("10000"),
- updatable: true,
- },
- {
- name: "[SDK finalised] Non-Updatable Module: Android.bp has older targetSdkVersion",
- platform_sdk_final: true,
- targetSdkVersionInBp: proptools.StringPtr("30"),
- targetSdkVersionExpected: proptools.StringPtr("30"),
- updatable: false,
- },
- {
- name: "[SDK finalised] Updatable Module: Android.bp has older targetSdkVersion",
- platform_sdk_final: true,
- targetSdkVersionInBp: proptools.StringPtr("30"),
- targetSdkVersionExpected: proptools.StringPtr("30"),
- updatable: true,
- },
- {
- name: "[SDK finalised] Updatable Module: Android.bp has targetSdkVersion as platform sdk codename",
- platform_sdk_final: true,
- targetSdkVersionInBp: proptools.StringPtr(platform_sdk_codename),
- targetSdkVersionExpected: proptools.StringPtr("33"),
- updatable: true,
- },
- {
- name: "[SDK finalised] Updatable Module: Android.bp has no targetSdkVersion",
- platform_sdk_final: true,
- targetSdkVersionExpected: proptools.StringPtr("33"),
- updatable: true,
- },
- }
- for _, testCase := range testCases {
- targetSdkVersionTemplate := ""
- if testCase.targetSdkVersionInBp != nil {
- targetSdkVersionTemplate = fmt.Sprintf(`target_sdk_version: "%s",`, *testCase.targetSdkVersionInBp)
- }
- bp := fmt.Sprintf(`
- android_app {
- name: "foo",
- sdk_version: "current",
- min_sdk_version: "29",
- %s
- updatable: %t,
- enforce_default_target_sdk_version: %t
- }
- `, targetSdkVersionTemplate, testCase.updatable, testCase.updatable) // enforce default target sdk version if app is updatable
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Platform_version_active_codenames = []string{platform_sdk_codename}
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
- result := fixture.RunTestWithBp(t, bp)
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+*testCase.targetSdkVersionExpected)
- }
- }
- func TestEnforceDefaultAppTargetSdkVersionFlag(t *testing.T) {
- platform_sdk_codename := "Tiramisu"
- platform_sdk_version := 33
- testCases := []struct {
- name string
- enforceDefaultTargetSdkVersion bool
- expectedError string
- platform_sdk_final bool
- targetSdkVersionInBp string
- targetSdkVersionExpected string
- updatable bool
- }{
- {
- name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
- enforceDefaultTargetSdkVersion: false,
- targetSdkVersionInBp: "29",
- targetSdkVersionExpected: "29",
- updatable: false,
- },
- {
- name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
- enforceDefaultTargetSdkVersion: true,
- platform_sdk_final: true,
- targetSdkVersionInBp: "current",
- targetSdkVersionExpected: "33",
- updatable: true,
- },
- {
- name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
- enforceDefaultTargetSdkVersion: true,
- platform_sdk_final: false,
- targetSdkVersionInBp: "current",
- targetSdkVersionExpected: "10000",
- updatable: false,
- },
- {
- name: "Not enforcing Target SDK Version for Updatable app",
- enforceDefaultTargetSdkVersion: false,
- expectedError: "Updatable apps must enforce default target sdk version",
- targetSdkVersionInBp: "29",
- targetSdkVersionExpected: "29",
- updatable: true,
- },
- }
- for _, testCase := range testCases {
- errExpected := testCase.expectedError != ""
- bp := fmt.Sprintf(`
- android_app {
- name: "foo",
- enforce_default_target_sdk_version: %t,
- sdk_version: "current",
- min_sdk_version: "29",
- target_sdk_version: "%v",
- updatable: %t
- }
- `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp, testCase.updatable)
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
- errorHandler := android.FixtureExpectsNoErrors
- if errExpected {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
- }
- result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
- if !errExpected {
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
- }
- }
- func TestEnforceDefaultAppTargetSdkVersionFlagForTests(t *testing.T) {
- platform_sdk_codename := "Tiramisu"
- platform_sdk_version := 33
- testCases := []struct {
- name string
- enforceDefaultTargetSdkVersion bool
- expectedError string
- platform_sdk_final bool
- targetSdkVersionInBp string
- targetSdkVersionExpected string
- }{
- {
- name: "Not enforcing Target SDK Version: Android.bp has older targetSdkVersion",
- enforceDefaultTargetSdkVersion: false,
- targetSdkVersionInBp: "29",
- targetSdkVersionExpected: "29",
- },
- {
- name: "[SDK finalised] Enforce Target SDK Version: Android.bp has current targetSdkVersion",
- enforceDefaultTargetSdkVersion: true,
- platform_sdk_final: true,
- targetSdkVersionInBp: "current",
- targetSdkVersionExpected: "33",
- },
- {
- name: "Enforce Target SDK Version: Android.bp has current targetSdkVersion",
- enforceDefaultTargetSdkVersion: true,
- platform_sdk_final: false,
- targetSdkVersionInBp: "current",
- targetSdkVersionExpected: "10000",
- },
- }
- for _, testCase := range testCases {
- errExpected := testCase.expectedError != ""
- bp := fmt.Sprintf(`
- android_test {
- name: "foo",
- enforce_default_target_sdk_version: %t,
- min_sdk_version: "29",
- target_sdk_version: "%v",
- }
- `, testCase.enforceDefaultTargetSdkVersion, testCase.targetSdkVersionInBp)
- fixture := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // explicitly set following platform variables to make the test deterministic
- variables.Platform_sdk_final = &testCase.platform_sdk_final
- variables.Platform_sdk_version = &platform_sdk_version
- variables.Platform_sdk_codename = &platform_sdk_codename
- variables.Unbundled_build = proptools.BoolPtr(true)
- variables.Unbundled_build_apps = []string{"sampleModule"}
- }),
- )
- errorHandler := android.FixtureExpectsNoErrors
- if errExpected {
- errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(testCase.expectedError)
- }
- result := fixture.ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, bp)
- if !errExpected {
- foo := result.ModuleForTests("foo", "android_common")
- manifestFixerArgs := foo.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
- }
- }
- func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAllowMissingDependencies,
- android.PrepareForTestWithAndroidMk,
- ).RunTestWithBp(t, `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- certificate: ":missing_certificate",
- sdk_version: "current",
- }
- android_app {
- name: "bar",
- srcs: ["a.java"],
- certificate: ":missing_certificate",
- product_specific: true,
- sdk_version: "current",
- }`)
- foo := result.ModuleForTests("foo", "android_common")
- fooApk := foo.Output("foo.apk")
- if fooApk.Rule != android.ErrorRule {
- t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
- }
- android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
- }
- func TestAppIncludesJniPackages(t *testing.T) {
- ctx := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- ).RunTestWithBp(t, `
- android_library_import {
- name: "aary-nodeps",
- aars: ["aary.aar"],
- extract_jni: true,
- }
- android_library {
- name: "aary-lib",
- sdk_version: "current",
- min_sdk_version: "21",
- static_libs: ["aary-nodeps"],
- }
- android_app {
- name: "aary-lib-dep",
- sdk_version: "current",
- min_sdk_version: "21",
- manifest: "AndroidManifest.xml",
- static_libs: ["aary-lib"],
- use_embedded_native_libs: true,
- }
- android_app {
- name: "aary-import-dep",
- sdk_version: "current",
- min_sdk_version: "21",
- manifest: "AndroidManifest.xml",
- static_libs: ["aary-nodeps"],
- use_embedded_native_libs: true,
- }
- android_app {
- name: "aary-no-use-embedded",
- sdk_version: "current",
- min_sdk_version: "21",
- manifest: "AndroidManifest.xml",
- static_libs: ["aary-nodeps"],
- }`)
- testCases := []struct {
- name string
- hasPackage bool
- }{
- {
- name: "aary-import-dep",
- hasPackage: true,
- },
- {
- name: "aary-lib-dep",
- hasPackage: true,
- },
- {
- name: "aary-no-use-embedded",
- hasPackage: false,
- },
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- app := ctx.ModuleForTests(tc.name, "android_common")
- outputFile := "jnilibs.zip"
- jniOutputLibZip := app.MaybeOutput(outputFile)
- if jniOutputLibZip.Rule == nil && !tc.hasPackage {
- return
- }
- jniPackage := "arm64-v8a_jni.zip"
- inputs := jniOutputLibZip.Inputs
- foundPackage := false
- for i := 0; i < len(inputs); i++ {
- if strings.Contains(inputs[i].String(), jniPackage) {
- foundPackage = true
- }
- }
- if foundPackage != tc.hasPackage {
- t.Errorf("expected to find %v in %v inputs; inputs = %v", jniPackage, outputFile, inputs)
- }
- })
- }
- }
- func TestTargetSdkVersionMtsTests(t *testing.T) {
- platformSdkCodename := "Tiramisu"
- android_test := "android_test"
- android_test_helper_app := "android_test_helper_app"
- bpTemplate := `
- %v {
- name: "mytest",
- target_sdk_version: "%v",
- test_suites: ["othersuite", "%v"],
- }
- `
- testCases := []struct {
- desc string
- moduleType string
- targetSdkVersionInBp string
- targetSdkVersionExpected string
- testSuites string
- }{
- {
- desc: "Non-MTS android_test_apps targeting current should not be upgraded to 10000",
- moduleType: android_test,
- targetSdkVersionInBp: "current",
- targetSdkVersionExpected: platformSdkCodename,
- testSuites: "non-mts-suite",
- },
- {
- desc: "MTS android_test_apps targeting released sdks should not be upgraded to 10000",
- moduleType: android_test,
- targetSdkVersionInBp: "29",
- targetSdkVersionExpected: "29",
- testSuites: "mts-suite",
- },
- {
- desc: "MTS android_test_apps targeting current should be upgraded to 10000",
- moduleType: android_test,
- targetSdkVersionInBp: "current",
- targetSdkVersionExpected: "10000",
- testSuites: "mts-suite",
- },
- {
- desc: "MTS android_test_helper_apps targeting current should be upgraded to 10000",
- moduleType: android_test_helper_app,
- targetSdkVersionInBp: "current",
- targetSdkVersionExpected: "10000",
- testSuites: "mts-suite",
- },
- }
- fixture := android.GroupFixturePreparers(
- prepareForJavaTest,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.Platform_sdk_codename = &platformSdkCodename
- variables.Platform_version_active_codenames = []string{platformSdkCodename}
- }),
- )
- for _, testCase := range testCases {
- result := fixture.RunTestWithBp(t, fmt.Sprintf(bpTemplate, testCase.moduleType, testCase.targetSdkVersionInBp, testCase.testSuites))
- mytest := result.ModuleForTests("mytest", "android_common")
- manifestFixerArgs := mytest.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
- android.AssertStringDoesContain(t, testCase.desc, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
- }
- }
- func TestPrivappAllowlist(t *testing.T) {
- testJavaError(t, "privileged must be set in order to use privapp_allowlist", `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- privapp_allowlist: "perms.xml",
- }
- `)
- result := PrepareForTestWithJavaDefaultModules.RunTestWithBp(
- t,
- `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
- privileged: true,
- sdk_version: "current",
- }
- override_android_app {
- name: "bar",
- base: "foo",
- package_name: "com.google.android.foo",
- }
- `,
- )
- app := result.ModuleForTests("foo", "android_common")
- overrideApp := result.ModuleForTests("foo", "android_common_bar")
- // verify that privapp allowlist is created for override apps
- overrideApp.Output("out/soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml")
- expectedAllowlistInput := "privapp_allowlist_com.android.foo.xml"
- overrideActualAllowlistInput := overrideApp.Rule("modifyAllowlist").Input.String()
- if expectedAllowlistInput != overrideActualAllowlistInput {
- t.Errorf("expected override allowlist to be %q; got %q", expectedAllowlistInput, overrideActualAllowlistInput)
- }
- // verify that permissions are copied to device
- app.Output("out/soong/target/product/test_device/system/etc/permissions/foo.xml")
- overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/bar.xml")
- }
- func TestPrivappAllowlistAndroidMk(t *testing.T) {
- result := android.GroupFixturePreparers(
- PrepareForTestWithJavaDefaultModules,
- android.PrepareForTestWithAndroidMk,
- ).RunTestWithBp(
- t,
- `
- android_app {
- name: "foo",
- srcs: ["a.java"],
- privapp_allowlist: "privapp_allowlist_com.android.foo.xml",
- privileged: true,
- sdk_version: "current",
- }
- override_android_app {
- name: "bar",
- base: "foo",
- package_name: "com.google.android.foo",
- }
- `,
- )
- baseApp := result.ModuleForTests("foo", "android_common")
- overrideApp := result.ModuleForTests("foo", "android_common_bar")
- baseAndroidApp := baseApp.Module().(*AndroidApp)
- baseEntries := android.AndroidMkEntriesForTest(t, result.TestContext, baseAndroidApp)[0]
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find foo.apk",
- baseEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
- "\\S+foo.apk",
- )
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include foo.apk",
- baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "\\S+foo.apk",
- )
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
- baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "\\S+foo.apk:\\S+/target/product/test_device/system/priv-app/foo/foo.apk",
- )
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
- baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml",
- )
- overrideAndroidApp := overrideApp.Module().(*AndroidApp)
- overrideEntries := android.AndroidMkEntriesForTest(t, result.TestContext, overrideAndroidApp)[0]
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALLED_MODULE; expected to find bar.apk",
- overrideEntries.EntryMap["LOCAL_SOONG_INSTALLED_MODULE"][0],
- "\\S+bar.apk",
- )
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include bar.apk",
- overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "\\S+bar.apk",
- )
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include app",
- overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "\\S+bar.apk:\\S+/target/product/test_device/system/priv-app/bar/bar.apk",
- )
- android.AssertStringMatches(
- t,
- "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
- overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml",
- )
- }
|