package Ġcom . zh uz ich u . mv vm . base ĊĊ Ċ import Ġandroid . os . Binder Ċ import Ġandroid . os . IB inder Ċ import Ġandroid . os . Parcel Ċ import Ġandroid . util . Base 6 4 Ċ import Ġandroid . util . Log Ċ import Ġjava . lang . reflect . Invocation TargetException Ċ import Ġjava . lang . reflect . Method Ċ import Ġjava . lang . reflect . Proxy Ċ import Ġjava . security . Message Digest Ċ import Ġjava . util . concurrent . Concurrent HashMap ĊĊ Ċ class ĠOk Binder ( private Ġval Ġremote Object : ĠAny ) Ġ: ĠB inder () Ġ{ ĊĠĠĠ Ġprivate Ġval Ġremote Methods Ġ= ĠConcurrent HashMap < String , ĠMethod >() ĊĠĠĠ Ġprivate Ġval Ġdescriptor : ĠString ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġremote Interface Ġ= Ġ( remote Object . java Class . interfaces Ġ?: Ġempty Array ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . is Ok Binder Interface () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. also Ġ{ Ġrequire ( it . size Ġ== Ġ 1 ) Ġ{ Ġ" remote Ġobject Ġmust Ġimplement Ġonly Ġone Ġinterface Ġwith Ġ@ Ok Binder . Interface Ġannotation " Ġ} Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. first () ĊĠĠĠĠĠĠĠ Ġfor Ġ( method Ġin Ġremote Interface . methods ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method . is Bridge ) Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġremote Methods [ getMethod Id ( method )] Ġ= Ġmethod ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdescriptor Ġ= Ġremote Interface . name ĊĠĠĠĠĠĠĠ Ġattach Interface ({ Ġthis Ġ}, Ġdescriptor ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Transact ( code : ĠInt , Ġdata : ĠParcel , Ġreply : ĠParcel ?, Ġflags : ĠInt ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire NotNull ( reply ) ĊĠĠĠĠĠĠĠ Ġif Ġ( code Ġ== ĠI Binder . FIRST _ CALL _ TRANSACTION ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . enforce Interface ( descriptor ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremote Method Ġ= Ġremote Methods . getValue ( data . readString () !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparam Types Ġ= Ġremote Method . parameter Types ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġif Ġ( param Types . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Method . invoke ( remote Object ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclass Loader Ġ= Ġremote Object . java Class . class Loader ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremote Method . invoke ( remote Object , Ġ* run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠArray ( param Types . size ) Ġ{ Ġadapt To Proxy ( data . readValue ( class Loader ), Ġparam Types [ it ]) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreply . write No Exception () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( result Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreply . writeInt ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreply . writeValue ( adapt To Binder ( result , Ġremote Method . returnType )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreply . writeInt ( 0 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcause Ġ= Ġe . cause . take If Ġ{ Ġe Ġis ĠInvocation TargetException Ġ} Ġ?: Ġe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLog . e ("@ Ok Binder ", Ġ" from ĠService ", Ġcause ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġcause ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . on Transact ( code , Ġdata , Ġreply , Ġflags ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Target ( Annotation Target . CLASS ) ĊĠĠĠ Ġannotation Ġclass ĠInterface ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠ Ġfun Ġ< T > Ġproxy ( binder : ĠI Binder , Ġservice Class : ĠClass < T >): ĠT Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequire ( service Class . is Ok Binder Interface ()) Ġ{ Ġ" class Ġmust Ġbe Ġan Ġinterface Ġwith Ġ@ Ok Binder . Interface Ġannotation " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( binder Ġis ĠOk Binder ) Ġreturn Ġbinder . remote Object Ġas ĠT ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclass Loader Ġ= Ġservice Class . class Loader ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġservice Class . cast ( Proxy . new Proxy Instance ( class Loader , ĠarrayOf ( service Class )) Ġ{ Ġ_, Ġmethod , Ġargs Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! binder . is Binder Alive ) Ġthrow ĠRuntimeException (" binder Ġhas Ġdi ed ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdata Ġ= ĠParcel . obtain () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreply Ġ= ĠParcel . obtain () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġresult : ĠAny ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . write Interface Token ( service Class . name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . writeString ( getMethod Id ( method )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġargs ?. forEach Indexed Ġ{ Ġindex , Ġarg Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . writeValue ( adapt To Binder ( arg , Ġmethod . parameter Types [ index ])) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflags Ġ= Ġif Ġ( method . returnType Ġ== ĠVoid . TYPE ) ĠI Binder . FLAG _ ONE WAY Ġelse Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbinder . transact ( IB inder . FIRST _ CALL _ TRANSACTION , Ġdata , Ġreply , Ġflags ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreply . read Exception () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( reply . readInt () Ġ!= Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġadapt To Proxy ( reply . readValue ( class Loader ) !! , Ġmethod . returnType ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreply . recycle () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdata . recycle () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}) !! ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġadapt To Binder ( value : ĠAny ?, Ġtype : ĠClass < *> ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( value Ġ!= Ġnull Ġ&& Ġtype . is Ok Binder Interface ()) ĠOk Binder ( value ) Ġelse Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġadapt To Proxy ( value : ĠAny ?, Ġtype : ĠClass < *> ): ĠAny ? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( value Ġ!= Ġnull Ġ&& Ġtype . is Ok Binder Interface ()) Ġproxy ( value Ġas ĠI Binder , Ġtype ) Ġelse Ġvalue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Method Id ( method : ĠMethod ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparams Ġ= Ġmethod . parameter Types . join ToString (",") Ġ{ Ġit . name Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Signature Ġ= Ġmethod . decl aring Class . name Ġ+ Ġ"." Ġ+ Ġmethod . name Ġ+ Ġ"@ " Ġ+ Ġparams ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmd 5 Ġ= ĠMessage Digest . getInstance (" MD 5 "). digest ( method Signature . toByteArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBase 6 4 . encode ToString ( md 5 , ĠBase 6 4 . NO _ WRAP ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun ĠClass <* >. is Ok Binder Interface (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġis Interface Ġ&& Ġis Annotation Present ( Interface :: class . java ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }