package Ġbr . com . simp li . ws Ċ Ċ import Ġcom . amazonaws . util . ClassLoader Helper Ċ import Ġcom . google . auth . oauth 2 . Google Credentials Ċ import Ġcom . google . gson . Gson Ċ import Ġcom . google . gson . Json Parser Ċ import Ġkotlinx . coroutines . Global Scope Ċ import Ġkotlinx . coroutines . async Ċ import Ġkotlinx . coroutines . await All Ċ import Ġkotlinx . coroutines . run Blocking Ċ import Ġorg . apache . logging . log 4 j . Log Manager Ċ import Ġjava . io . IOException Ċ import Ġjava . net . Http URLConnection Ċ import Ġjava . net . URL Ċ import Ġjava . net . URL Encoder Ċ import Ġjava . util .* Ċ import Ġjavax . net . ssl . Https URLConnection Ċ Ċ /** Ċ Ġ* Ġ@ author ĠJo ao Li ppi Ċ Ġ* Ġ@ since Ġ 2 0 1 9 / 1 0 / 1 7 Ċ Ġ*/ Ċ Ċ class ĠPush Android Ġprivate Ġconstructor ( private Ġval ĠapiKey : ĠString ?, Ġprivate Ġval Ġservices Json : ĠString , Ġprivate Ġval Ġfirebase : ĠBoolean , Ġprivate Ġval Ġlegacy : ĠBoolean ) Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlogger Ġ= ĠLog Manager . getLogger ( Push Android :: class . java ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Deprecated (" GCM Ġis Ġnot Ġsupported Ġanymore Ġand ĠF CM Ġlegacy Ġis Ġdeprecated ", ĠReplace With (" Push Android ( apiKey ) Ġor ĠPush Android ( apiKey , Ġservices Json ) ")) ĊĠĠĠ Ġconstructor ( apiKey : ĠString , Ġfirebase : ĠBoolean , Ġlegacy : ĠBoolean ) Ġ: Ġthis Ġ( apiKey , Ġ"/ firebase - service . json ", Ġfirebase , Ġlegacy ) ĊĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġconstructor ( services Json : ĠString Ġ= Ġ"/ firebase - service . json ") Ġ: Ġthis ( null , Ġservices Json , Ġtrue , Ġfalse ) ĊĊĠĠĠ Ġprivate Ġval ĠprojectId Ġ= Ġget ProjectId () ĊĊĠĠĠ Ġprivate Ġval Ġendpoint GCM Ġ= Ġ" https :// android . googleapis . com / gcm / send " ĊĠĠĠ Ġprivate Ġval Ġendpoint F MC Legacy Ġ= Ġ" https :// fc m . googleapis . com / fc m / send " ĊĠĠĠ Ġprivate Ġval Ġendpoint F CM Ġ= Ġ" https :// fc m . googleapis . com / v 1 / projects /$ projectId / messages : send " ĊĊĠĠĠ Ġprivate Ġval Ġscope Ġ= Ġ" https :// www . googleapis . com / auth / firebase . messaging " ĊĠĠĠ Ġprivate Ġval Ġmapper Ġ= ĠGson () ĊĊĊĠĠĠ Ġfun Ġsend ( text : ĠString , Ġvar arg Ġpush Tokens : ĠString ): ĠBatch Response Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsend ( text , Ġpush Tokens . toList ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsend ( text : ĠString , Ġpush Tokens : ĠList < String >): ĠBatch Response Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsend ( text , Ġpush Tokens , Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsend ( title : ĠString , Ġcontent : ĠString , Ġdata : ĠMap < String , ĠAny >, Ġvar arg Ġpush Tokens : ĠString ): ĠBatch Response Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsend ( title , Ġcontent , Ġdata , Ġpush Tokens . toList ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġfun Ġsend ( title : ĠString , Ġcontent : ĠString , Ġdata : ĠMap < String , ĠAny >? Ġ= Ġnull , Ġpush Tokens : ĠList < String >): ĠBatch Response Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! firebase Ġ|| Ġlegacy ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠUnsupportedOperationException (" Only Ġworks Ġwith ĠF CM ĠHTTP Ġv 1 ĠAPI ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġsend Firebase ( title , Ġcontent , Ġdata , Ġendpoint F CM , Ġpush Tokens ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Exception :: class ) ĊĠĠĠ Ġfun Ġsend ( text : ĠString , Ġpush Tokens : ĠList < String >, Ġencode : ĠBoolean ): ĠBatch Response Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġcontent Ġ= Ġif Ġ( encode ) ĠURL Encoder . encode ( text , Ġ" UTF - 8 ") Ġelse Ġtext ĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= Ġif Ġ( firebase Ġ&& Ġlegacy ) Ġendpoint F MC Legacy Ġelse Ġif Ġ( firebase ) Ġendpoint F CM Ġelse Ġendpoint GCM ĊĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( firebase Ġ&& Ġ! legacy ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Firebase ( content , Ġurl , Ġpush Tokens ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Legacy Or GCM ( content , Ġurl , Ġpush Tokens ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Firebase ( content : ĠString , Ġurl : ĠString , Ġpush Tokens : ĠList < String >) Ġ: ĠBatch Response Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠNew ĠFirebase ĠAPI Ġdoesn 't Ġsupport Ġmultiple Ġregistration ĠIDs Ġin Ġthe Ġsame Ġrequest Ġanymore ĊĠĠĠĠĠĠĠ Ġ// Ġunless Ġit 's Ġa Ġmultipart / mixed ĠPOST Ġrequest Ġwith Ġa Ġlimit Ġof Ġ 1 0 0 Ġtokens ĊĠĠĠĠĠĠĠ Ġval Ġlog Payload Ġ= Ġmapper . toJson ( payload ( content )) ĊĠĠĠĠĠĠĠ Ġlogger . debug (" Sending Ġpush : Ġ$ log Payload ") ĊĊĠĠĠĠĠĠĠ Ġreturn Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpush Tokens . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGlobal Scope . async Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse ( it , Ġpost ( url , Ġ Ġmapper . toJson ( payload ( content , Ġit )))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. await All () ĊĠĠĠĠĠĠĠ Ġ}. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBatch Response ( this ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Firebase ( title : ĠString , Ġtext : ĠString , Ġdata : ĠMap < String , ĠAny >? Ġ= Ġnull , Ġurl : ĠString , Ġpush Tokens : ĠList < String >) Ġ: ĠBatch Response Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// ĠNew ĠFirebase ĠAPI Ġdoesn 't Ġsupport Ġmultiple Ġregistration ĠIDs Ġin Ġthe Ġsame Ġrequest Ġanymore ĊĠĠĠĠĠĠĠ Ġ// Ġunless Ġit 's Ġa Ġmultipart / mixed ĠPOST Ġrequest Ġwith Ġa Ġlimit Ġof Ġ 1 0 0 Ġtokens ĊĠĠĠĠĠĠĠ Ġval Ġlog Payload Ġ= Ġmapper . toJson ( payload ( title , Ġtext , Ġdata )) ĊĠĠĠĠĠĠĠ Ġlogger . debug (" Sending Ġpush : Ġ$ log Payload ") ĊĊĠĠĠĠĠĠĠ Ġreturn Ġrun Blocking Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpush Tokens . map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠGlobal Scope . async Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResponse ( it , Ġpost ( url , Ġ Ġmapper . toJson ( payload ( title , Ġtext , Ġdata , Ġit )))) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. await All () ĊĠĠĠĠĠĠĠ Ġ}. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBatch Response ( this ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend Legacy Or GCM ( content : ĠString , Ġurl : ĠString , Ġpush Tokens : ĠList < String >) Ġ: ĠBatch Response Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġpayload Ġ= Ġmapper . toJson ( legacy Payload ( content , Ġpush Tokens )) ĊĠĠĠĠĠĠĠ Ġlogger . debug (" Sending Ġpush Ġ( legacy ): Ġ$ payload ") ĊĊĠĠĠĠĠĠĠ Ġreturn ĠBatch Response ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResponse ( push Tokens , Ġpost ( url , Ġpayload )). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpost ( url : ĠString , Ġparameters : ĠString ): ĠHttp s URLConnection Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ( URL ( url ). open Connection () Ġas ĠHttp s URLConnection ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest Method Ġ= Ġ" POST " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset Request Property (" Content - Type ", Ġ" application / json ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( legacy ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Request Property (" Authorization ", Ġ" key =$ apiKey ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġset Request Property (" Authorization ", Ġ" Bearer Ġ${ get AuthToken () }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Output Ġ= Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ ĠoutputStream . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( parameters . toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġflush () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclose () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlegacy Payload ( content : ĠString , Ġpush Tokens : ĠList < String >): ĠMap < String , ĠAny > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠHashMap < String , ĠAny >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" registration _ ids "] Ġ= Ġpush Tokens ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" data "] Ġ= ĠHashMap < String , ĠString >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" message "] Ġ= Ġcontent ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpayload ( content : ĠString , Ġpush Token : ĠString ? Ġ= Ġnull ): ĠMap < String , ĠAny > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġpayload ( null , Ġnull , Ġmap Of (" message " Ġto Ġcontent ), Ġpush Token ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġpayload ( title : ĠString ? Ġ= Ġnull , Ġcontent : ĠString ? Ġ= Ġnull , Ġdata : ĠMap < String , ĠAny >? Ġ= Ġnull , Ġpush Token : ĠString ? Ġ= Ġnull ): ĠMap < String , ĠAny > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠHashMap < String , ĠAny >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" message "] Ġ= ĠHashMap < String , ĠAny >(). apply Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! title . isNull OrEmpty () Ġ|| Ġ! content . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" notification "] Ġ= ĠHashMap < String , ĠAny >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtitle ?. also Ġ{ Ġthis [" title "] Ġ= Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontent ?. also Ġ{ Ġthis [" body "] Ġ= Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata ?. also Ġ{ Ġthis [" data "] Ġ= Ġit Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpush Token ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [" token "] Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget ProjectId () Ġ: ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠClassLoader Helper . getResource AsStream ( services Json )?. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJson Parser () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. parse ( reader ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . as JsonObject ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . get (" project _ id ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . asString ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġget AuthToken (): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠClassLoader Helper . getResource AsStream ( services Json )?. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠGoogle Credentials ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. from Stream ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. create Scoped ( scope ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrefresh If Expired () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠaccessToken . token Value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠResponse ( tokens : ĠList < String >, Ġcon : ĠHttp s URLConnection ) Ġ: ĠLog gable Ġ{ ĊĠĠĠĠĠĠĠ Ġconstructor ( token : ĠString , Ġcon : ĠHttp s URLConnection ) Ġ: Ġthis ( listOf ( token ), Ġcon ) ĊĊĠĠĠĠĠĠĠ Ġval Ġtokens Ġ= Ġtokens . join ToString () ĊĠĠĠĠĠĠĠ Ġval Ġresponse Code : ĠInt Ġ= Ġcon . response Code ĊĠĠĠĠĠĠĠ Ġval Ġresponse Message Ġ= ĠStringBuilder (). run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcon . inputStream ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcon . error Stream ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ?. reader ()?. read Lines ()?. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . append ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġlog () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug ( this . response Message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠBatch Response ( val Ġresponses : ĠList < Response >) Ġ: ĠLog gable Ġ{ ĊĠĠĠĠĠĠĠ Ġconstructor ( var arg Ġresponses : ĠResponse ) Ġ: Ġthis ( responses . toList ()) ĊĊĠĠĠĠĠĠĠ Ġval Ġsuc cesses Ġ= Ġresponses . count Ġ{ Ġit . response Code . success () Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġfailures Ġ= Ġresponses . count Ġ{ Ġ! it . response Code . success () Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġfailed Tokens Ġ= Ġresponses . filter Ġ{ Ġ! it . response Code . success () Ġ}. map Ġ{ Ġit . tokens Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġlog () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . debug ( log Message ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun ĠlogMessage (): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSuccessful Ġp ushes : Ġ$ suc cesses ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFailed Ġp ushes : Ġ$ failures ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFailed Ġtokens : Ġ${ failed Tokens . join ToString ()} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun ĠInt . success (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis Ġ< ĠHttp URLConnection . HTTP _ BAD _ REQUEST ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinterface ĠLog gable Ġ{ ĊĠĠĠĠĠĠĠ Ġfun Ġlog () ĊĠĠĠ Ġ} Ċ Ċ } Ċ