/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 9 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* Ġ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 Ġcom . android . tools . idea . gradle . project . sync . idea . sv s Ċ Ċ import Ġcom . android . Android Project Types . PROJECT _ TYPE _ APP Ċ import Ġcom . android . builder . model . Model Builder Parameter Ċ import Ġcom . android . builder . model . Native Variant Ab i Ċ import Ġcom . android . builder . model . Variant Ċ import Ġcom . android . tools . idea . gradle . project . sync . Modules . create Unique Module Id Ċ import Ġcom . android . tools . idea . gradle . project . sync . idea . Used In Build Action Ċ import Ġcom . android . tools . idea . gradle . project . sync . Selected Variants Ċ import Ġcom . android . tools . idea . gradle . project . sync . Sync Action Options Ċ import Ġorg . gradle . tool ing . Build Controller Ċ import Ġorg . gradle . tool ing . model . Unsupported Method Exception Ċ import Ġjava . util . Collections Ċ import Ġjava . util . LinkedList Ċ Ċ /** Ċ Ġ* ĠThis Ġmethod Ġrequests Ġall Ġof Ġthe Ġrequired Ġ[ Variant ] Ġmodels Ġfrom ĠGradle Ġvia Ġthe Ġtool ing ĠAPI . Ċ Ġ* Ċ Ġ* ĠFunction Ġfor Ġchoosing Ġthe Ġbuild Ġvariant Ġthat Ġwill Ġbe Ġselected Ġin ĠAndroid ĠStudio Ġ( the ĠIDE Ġcan Ġonly Ġwork Ġwith Ġone Ġvariant Ġat Ġa Ġtime .) Ċ Ġ* Ġworks Ġas Ġfollows : Ċ Ġ* ĠĠ 1 . ĠFor ĠAndroid Ġapp Ġmodules Ġusing Ġnew Ġversions Ġof Ġthe Ġplugin , Ġthe Ġ[ Variant ] Ġto Ġselect Ġis Ġobtained Ġfrom Ġthe Ġmodel . Ċ Ġ* ĠĠĠĠ ĠFor Ġolder Ġplugins , Ġthe Ġ" debug " Ġvariant Ġis Ġselected . ĠIf Ġthe Ġmodule Ġdoesn 't Ġhave Ġa Ġvariant Ġnamed Ġ" debug ", Ġit Ġsorts Ġall Ġthe Ċ Ġ* ĠĠĠĠ Ġvariant Ġnames Ġalphabet ically Ġand Ġp icks Ġthe Ġfirst Ġone . Ċ Ġ* ĠĠ 2 . ĠFor ĠAndroid Ġlibrary Ġmodules , Ġit Ġch oo ses Ġthe Ġvariant Ġneeded Ġby Ġdependent Ġmodules . ĠFor Ġexample , Ġif Ġvariant Ġ" debug " Ġin Ġmodule Ġ" app " Ċ Ġ* ĠĠĠĠ Ġdepends Ġon Ġmodule Ġ" lib " Ġ- Ġvariant Ġ" free Debug ", Ġthe Ġselected Ġvariant Ġin Ġ" lib " Ġwill Ġbe Ġ" free Debug ". ĠIf Ġa Ġlibrary Ġmodule Ġis Ġa Ġleaf Ċ Ġ* ĠĠĠĠ Ġ( i . e . Ġno Ġother Ġmodules Ġdepend Ġon Ġit ) Ġa Ġvariant Ġwill Ġbe Ġpicked Ġas Ġif Ġthe Ġmodule Ġwas Ġan Ġapp Ġmodule . Ċ Ġ* Ċ Ġ* Ġ ĠAll Ġof Ġthe Ġ[ Variant ] Ġor Ġ[ Native Variant Ab i ] Ġmodels Ġobtained Ġfrom ĠGradle Ġare Ġstored Ġin Ġthe Ġ[ Android Module ] s Ġ[ Variant Group ] Ċ Ġ* Ġ Ġonce Ġthis Ġmethod Ġreturns . Ċ Ġ*/ Ċ @ Used In Build Action Ċ fun Ġchoose Selected Variants ( ĊĠ Ġcontroller : ĠBuild Controller , ĊĠ Ġinput Modules : ĠList < Android Module >, ĊĠ Ġsync Action Options : ĠSync Action Options Ċ ) Ġ{ ĊĠ Ġval Ġselected Variants Ġ= Ġsync Action Options . selected Variants ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalStateException (" Single Ġvariant Ġsync Ġrequested , Ġbut ĠSelected Variants Ġwere Ġnull !") ĊĠ Ġval Ġmodules ById Ġ= ĠHashMap < String , ĠAndroid Module >() ĊĠ Ġval Ġall Modules Ġ= ĠLinkedList < String >() ĊĠ Ġval Ġvisited Modules Ġ= ĠHashSet < String >() ĊĠ Ġ// ĠThe Ġmodule Ġwhose Ġvariant Ġselection Ġwas Ġchanged Ġfrom ĠUI , Ġthe Ġdependency Ġmodules Ġshould Ġbe Ġconsistent Ġwith Ġthis Ġmodule . ĠA ch ieve Ġthis Ġby ĊĠ Ġ// Ġadding Ġthis Ġmodule Ġto Ġthe Ġhead Ġof Ġall Modules Ġso Ġthat Ġits Ġdependency Ġmodules Ġare Ġresolved Ġfirst . ĊĠ Ġvar Ġmodule With Variant Sw itched : ĠString ? Ġ= Ġnull ĊĊĠ Ġinput Modules . filter Ġ{ Ġit . android Project . variants . isEmpty () Ġ}. forEach Ġ{ Ġmodule Ġ-> ĊĠĠĠ Ġval Ġid Ġ= Ġcreate Unique Module Id ( module . gradle Project ) ĊĠĠĠ Ġmodules ById [ id ] Ġ= Ġmodule ĊĠĠĠ Ġif Ġ( id Ġ== Ġsync Action Options . module Id With Variant Sw itched ) Ġ{ ĊĠĠĠĠĠ Ġmodule With Variant Sw itched Ġ= Ġid ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġ// ĠAll Ġapp Ġmodules Ġmust Ġbe Ġrequested Ġfirst Ġsince Ġthey Ġare Ġused Ġto Ġwork Ġout Ġwhich Ġvariants Ġto Ġrequest Ġfor Ġtheir Ġdependencies . ĊĠĠĠĠĠ Ġif Ġ( module . android Project . project Type Ġ== ĠPROJECT _ TYPE _ APP ) Ġall Modules . add First ( id ) Ġelse Ġall Modules . add Last ( id ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġif Ġ( module With Variant Sw itched Ġ!= Ġnull ) Ġall Modules . add First ( module With Variant Sw itched ) ĊĊĠ Ġ// ĠThis Ġfirst Ġstarts Ġby Ġrequesting Ġmodels Ġfor Ġall Ġthe Ġmodules Ġthat Ġcan Ġbe Ġreached Ġfrom Ġthe Ġapp Ġmodules Ġ( via Ġdependencies ) Ġand Ġthen ĊĠ Ġ// Ġrequests Ġany Ġother Ġmodules Ġthat Ġcan 't Ġbe Ġreached . ĊĠ Ġall Modules . forEach Ġ{ Ġmodule Id Ġ-> ĊĠĠĠ Ġif Ġ( visited Modules . contains ( module Id )) Ġreturn @ forEach ĊĊĠĠĠ Ġvisited Modules . add ( module Id ) ĊĠĠĠ Ġval Ġmodule Ġ= Ġmodules ById [ module Id ] !! ĊĊĠĠĠ Ġ// ĠRequest Ġthe ĠVariant Ġmodel Ġfor Ġthe Ġmodule ĊĠĠĠ Ġval Ġvariant Ġ= Ġselect Variant For App Or Leaf ( controller , Ġmodule , Ġselected Variants , Ġmodule Id ) Ġ?: Ġreturn @ forEach ĊĠĠĠ Ġ// ĠRequest Ġthe Ġnative ĠVariant Ġmodel Ġ( this Ġwon 't Ġdo Ġany Ġwork Ġfor Ġnon - native Ġprojects ) Ġand Ġget Ġthe Ġname Ġof Ġit 's ĠABI ĊĠĠĠ Ġval Ġabi Ġ= Ġsync And Add Native Variant Ab i ( controller , Ġmodule , Ġvariant . name , Ġselected Variants . getSelected Ab i ( module Id )) ĊĠĠĠ Ġ// ĠStore Ġthe Ġrequested / obt ained Ġinformation Ġin Ġthe ĠIde a Android Module ĊĠĠĠ Ġmodule . add Selected Variant ( variant , Ġabi ) ĊĠĠĠ Ġ// ĠRequest Ġmodels Ġfor Ġthe Ġdependencies Ġof Ġthis Ġmodule . ĊĠĠĠ Ġselect Variant For Dependency Modules ( controller , Ġmodule , Ġmodules ById , Ġvisited Modules ) ĊĠ Ġ} Ċ } Ċ Ċ @ Used In Build Action Ċ private Ġfun Ġselect Variant For App Or Leaf ( ĊĠ Ġcontroller : ĠBuild Controller , ĊĠ Ġandroid Module : ĠAndroid Module , ĊĠ Ġselected Variants : ĠSelected Variants , ĊĠ Ġmodule Id : ĠString Ċ ): ĠVariant ? Ġ{ ĊĠ Ġvar Ġvariant Ġ= Ġselected Variants . getSelected Variant ( module Id ) ĊĠ Ġval Ġvariant Names Ġ= Ġtry Ġ{ ĊĠĠĠ Ġandroid Module . android Project . variant Names ĊĠ Ġ} Ġcatch Ġ( e : ĠUnsupported Method Exception ) Ġ{ ĊĠĠĠ Ġnull ĊĠ Ġ} Ġ?: Ġreturn Ġnull ĊĊĠ Ġ// ĠCheck Ġto Ġsee Ġif Ġwe Ġhave Ġa Ġvariant Ġselected Ġin Ġthe ĠIDE , Ġand Ġthat Ġit Ġis Ġstill Ġa Ġvalid Ġone . ĊĠ Ġif Ġ( variant Ġ== Ġnull Ġ|| Ġ! variant Names . contains ( variant )) Ġ{ ĊĠĠĠ Ġvariant Ġ= Ġtry Ġ{ ĊĠĠĠĠĠ Ġ// ĠAsk ĠGradle Ġfor Ġthe Ġdefault Variant ĊĠĠĠĠĠ Ġandroid Module . android Project . default Variant ĊĠĠĠ Ġ} ĊĠĠĠ Ġcatch Ġ( e : ĠUnsupported Method Exception ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠIf Ġthis Ġis Ġnot Ġsupported Ġthen Ġfallback Ġto Ġpicking Ġa Ġdefault . ĊĠĠĠĠĠ ĠgetDefault Or First Item ( variant Names , Ġ" debug ") ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġreturn Ġvariant ?. let Ġ{ Ġsync And Add Variant ( controller , Ġandroid Module , Ġvariant ) Ġ} Ċ } Ċ Ċ @ Used In Build Action Ċ private Ġfun Ġselect Variant For Dependency Modules ( ĊĠ Ġcontroller : ĠBuild Controller , ĊĠ Ġandroid Module : ĠAndroid Module , ĊĠ Ġmodules ById : ĠMap < String , ĠAndroid Module >, ĊĠ Ġvisited Modules : ĠMutable Set < String > Ċ ) Ġ{ ĊĠ Ġandroid Module . module Dependencies . forEach Ġ{ Ġdependency Ġ-> ĊĠĠĠ Ġif Ġ( visited Modules . contains ( dependency . id )) Ġreturn @ forEach ĊĠĠĠ Ġvisited Modules . add ( dependency . id ) ĊĊĠĠĠ Ġif Ġ( dependency . variant Ġ== Ġnull ) Ġreturn @ forEach ĊĊĠĠĠ Ġval Ġdependency Module Ġ= Ġmodules ById [ dependency . id ] Ġ?: Ġreturn @ forEach ĊĠĠĠ Ġif Ġ( dependency Module . contains Variant ( dependency . variant )) Ġreturn @ forEach ĊĊĠĠĠ Ġval Ġdependency Variant Ġ= Ġsync And Add Variant ( controller , Ġdependency Module , Ġdependency . variant ) Ġ?: Ġreturn @ forEach ĊĠĠĠ Ġval Ġabi Name Ġ= Ġsync And Add Native Variant Ab i ( controller , Ġdependency Module , Ġdependency . variant , Ġdependency . abi ) ĊĊĠĠĠ Ġdependency Module . add Selected Variant ( dependency Variant , Ġabi Name ) ĊĠĠĠ Ġselect Variant For Dependency Modules ( controller , Ġdependency Module , Ġmodules ById , Ġvisited Modules ) ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠQuery ĠGradle Ġfor Ġthe Ġ[ Variant ] Ġof Ġthe Ġ[ module ] Ġwith Ġthe Ġgiven Ġ[ variant Name ]. ĠGradle 's Ġparameter ized Ġtool ing ĠAPI Ġis Ġused Ġin Ġorder Ċ Ġ* Ġto Ġpass Ġthe Ġname Ġof Ġthe Ġvariant Ġand Ġwhether Ġor Ġnot Ġsources Ġshould Ġbe Ġgenerated Ġto Ġthe ĠModel Builder Ġvia Ġthe Ġ[ Model Builder Parameter ]. Ċ Ġ* Ċ Ġ* ĠThis Ġmethod Ġadds Ġthe Ġresulting Ġ[ Variant ] Ġto Ġthe Ġ[ module ] s Ġ[ Variant Group ] Ġif Ġnot Ġnull . ĠIf Ġno Ġmodel Ġis Ġreturned , Ġnothing Ġis Ġadded . Ċ Ġ* Ċ Ġ* Ġ@ param [ module ] Ġthe Ġmodule Ġto Ġrequest Ġa Ġ[ Variant ] Ġfor Ċ Ġ* Ġ@ param [ controller ] Ġthe ĠGradle Ġ[ Build Controller ] Ġthat Ġis Ġqueried Ġfor Ġthe Ġmodel Ċ Ġ* Ġ@ param [ variant Name ] Ġthe Ġname Ġof Ġthe Ġ[ Variant ] Ġthat Ġshould Ġbe Ġrequested Ċ Ġ*/ Ċ @ Used In Build Action Ċ private Ġfun Ġsync And Add Variant ( ĊĠ Ġcontroller : ĠBuild Controller , ĊĠ Ġmodule : ĠAndroid Module , ĊĠ Ġvariant Name : ĠString Ċ ): ĠVariant ? Ġ= Ġcontroller . find Model ( module . gradle Project , ĠVariant :: class . java , ĠModel Builder Parameter :: class . java ) Ġ{ Ġparameter Ġ-> ĊĠ Ġparameter . set Variant Name ( variant Name ) Ċ } ?. also Ġ{ ĊĠ Ġmodule . variant Group . variants . add ( it ) Ċ } Ċ Ċ /** Ċ Ġ* ĠQuery ĠGradle Ġfor Ġthe Ġabi Ġname Ġof Ġthe Ġ[ module ] Ġwith Ġthe Ġgiven Ġ[ variant Name ]. ĠGradle 's Ġparameter ized Ġtool ing ĠAPI Ġis Ġused Ġin Ġorder Ċ Ġ* Ġto Ġpass Ġthe Ġname Ġof Ġthe Ġvariant Ġand Ġthe Ġabi Ġname Ġto Ġthe ĠModel Builder Ġvia Ġthe Ġ[ Model Builder Parameter ]. Ċ Ġ* Ċ Ġ* ĠIf Ġthe Ġpassed Ġ[ module ] Ġdoesn 't Ġhave Ġa ĠNative Android Project Ġthen Ġthis Ġmethod Ġdoes Ġnothing . Ċ Ġ* Ċ Ġ* ĠThis Ġmethod Ġadds Ġthe Ġresulting Ġ[ Native Variant Ab i ] Ġto Ġthe Ġ[ module ] s Ġ[ Variant Group ] Ġif Ġnot Ġnull . ĠIf Ġno Ġmodel Ġis Ġreturned , Ġnothing Ġis Ġadded . Ċ Ġ* Ċ Ġ* Ġ@ param [ module ] Ġthe Ġmodule Ġto Ġrequest Ġa Ġ[ Variant ] Ġfor Ċ Ġ* Ġ@ param [ controller ] Ġthe ĠGradle Ġ[ Build Controller ] Ġthat Ġis Ġqueried Ġfor Ġthe Ġmodel Ċ Ġ* Ġ@ param [ variant Name ] Ġthe Ġname Ġof Ġthe Ġ[ Variant ] Ġthat Ġshould Ġbe Ġrequested Ċ Ġ* Ġ@ param [ selected Ab i ] Ġwhich Ġabi Ġto Ġselect , Ġif Ġnull Ġor Ġthe Ġabi Ġdoesn 't Ġexist Ġa Ġdefault Ġwill Ġbe Ġpicked . ĠThis Ġdefault Ġwill Ġbe Ġ" x 8 6 " Ġif Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġexists Ġin Ġthe Ġabi Ġnames Ġreturned Ġby Ġthe Ġ[ Native Android Project ] Ġotherwise Ġthe Ġfirst Ġitem Ġof Ġthis Ġlist Ġwill Ġbe Ċ Ġ* ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchosen . Ċ Ġ*/ Ċ @ Used In Build Action Ċ private Ġfun Ġsync And Add Native Variant Ab i ( ĊĠ Ġcontroller : ĠBuild Controller , ĊĠ Ġmodule : ĠAndroid Module , ĊĠ Ġvariant Name : ĠString , ĊĠ Ġselected Ab i : ĠString ? Ċ ): ĠString ? Ġ{ ĊĠ Ġ// ĠThis Ġmodule Ġis Ġnot Ġa Ġnative Ġone , Ġnothing Ġto Ġdo ĊĠ Ġif Ġ( module . native Android Project Ġ== Ġnull ) Ġreturn Ġnull ĊĊĠ Ġ// ĠAttempt Ġto Ġget Ġthe Ġlist Ġof Ġsupported Ġabi Names Ġfor Ġthis Ġvariant Ġfrom Ġthe ĠNative Android Project ĊĠ Ġ// ĠOtherwise Ġreturn Ġfrom Ġthis Ġmethod Ġwith Ġa Ġnull Ġresult Ġas Ġab is Ġare Ġnot Ġsupported . ĊĠ Ġval Ġabi Names Ġ= Ġtry Ġ{ ĊĠĠĠ Ġmodule . native Android Project . variant Infos [ variant Name ]?. abi Names ĊĠ Ġ} ĊĠ Ġcatch Ġ( e : ĠUnsupported Method Exception ) Ġ{ ĊĠĠĠ Ġnull ĊĠ Ġ} Ġ?: Ġreturn Ġnull ĊĊĠ Ġval Ġabi To Request Ġ= Ġ( if Ġ( selected Ab i Ġ!= Ġnull Ġ&& Ġabi Names . contains ( selected Ab i )) Ġselected Ab i Ġelse ĠgetDefault Or First Item ( abi Names , Ġ" x 8 6 ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalStateException (" No Ġvalid ĠNative Ġabi Ġfound Ġto Ġrequest !") ĊĊĠ Ġcontroller . find Model ( module . gradle Project , ĠNative Variant Ab i :: class . java , ĠModel Builder Parameter :: class . java ) Ġ{ Ġparameter Ġ-> ĊĠĠĠ Ġparameter . set Variant Name ( variant Name ) ĊĠĠĠ Ġparameter . set Ab i Name ( abi To Request ) ĊĠ Ġ} ?. also Ġ{ ĊĠĠĠ Ġmodule . variant Group . native Variants . add ( it ) ĊĠ Ġ} ĊĠ Ġreturn Ġabi To Request Ċ } Ċ Ċ @ Used In Build Action Ċ private Ġfun ĠgetDefault Or First Item ( names : ĠCollection < String >, ĠdefaultValue : ĠString ): ĠString ? Ġ{ ĊĠ Ġif Ġ( names . isEmpty ()) Ġreturn Ġnull ĊĠ Ġreturn Ġif Ġ( names . contains ( defaultValue )) ĠdefaultValue Ġelse ĠCollections . min ( names , ĠString :: compareTo ) Ċ } ĊĊ