32
32
import com .google .common .annotations .VisibleForTesting ;
33
33
import com .google .common .base .Ticker ;
34
34
import com .google .common .base .Verify ;
35
+ import com .google .common .util .concurrent .FutureCallback ;
36
+ import com .google .common .util .concurrent .Futures ;
35
37
import com .google .common .util .concurrent .ListenableFuture ;
36
38
import io .grpc .Attributes ;
37
39
import io .grpc .CallOptions ;
47
49
import io .grpc .Status ;
48
50
import io .grpc .StatusException ;
49
51
import io .grpc .binder .AndroidComponentAddress ;
52
+ import io .grpc .binder .AsyncSecurityPolicy ;
50
53
import io .grpc .binder .InboundParcelablePolicy ;
51
54
import io .grpc .binder .SecurityPolicy ;
52
55
import io .grpc .internal .ClientStream ;
@@ -743,8 +746,8 @@ void notifyTerminated() {
743
746
@ Override
744
747
@ GuardedBy ("this" )
745
748
protected void handleSetupTransport (Parcel parcel ) {
746
- // Add the remote uid to our attributes.
747
- attributes = setSecurityAttrs (attributes , Binder . getCallingUid () );
749
+ int remoteUid = Binder . getCallingUid ();
750
+ attributes = setSecurityAttrs (attributes , remoteUid );
748
751
if (inState (TransportState .SETUP )) {
749
752
int version = parcel .readInt ();
750
753
IBinder binder = parcel .readStrongBinder ();
@@ -755,46 +758,54 @@ protected void handleSetupTransport(Parcel parcel) {
755
758
shutdownInternal (
756
759
Status .UNAVAILABLE .withDescription ("Malformed SETUP_TRANSPORT data" ), true );
757
760
} else {
758
- offloadExecutor .execute (() -> checkSecurityPolicy (binder ));
761
+ ListenableFuture <Status > authFuture = (securityPolicy instanceof AsyncSecurityPolicy ) ?
762
+ ((AsyncSecurityPolicy ) securityPolicy ).checkAuthorizationAsync (remoteUid ) :
763
+ Futures .submit (() -> securityPolicy .checkAuthorization (remoteUid ), offloadExecutor );
764
+ Futures .addCallback (
765
+ authFuture ,
766
+ new FutureCallback <Status >() {
767
+ @ Override
768
+ public void onSuccess (Status result ) { handleAuthResult (binder , result ); }
769
+
770
+ @ Override
771
+ public void onFailure (Throwable t ) { handleAuthResult (t ); }
772
+ },
773
+ offloadExecutor );
759
774
}
760
775
}
761
776
}
762
777
763
- private void checkSecurityPolicy (IBinder binder ) {
764
- Status authorization ;
765
- Integer remoteUid ;
766
- synchronized (this ) {
767
- remoteUid = attributes .get (REMOTE_UID );
768
- }
769
- if (remoteUid == null ) {
770
- authorization = Status .UNAUTHENTICATED .withDescription ("No remote UID available" );
771
- } else {
772
- authorization = securityPolicy .checkAuthorization (remoteUid );
773
- }
774
- synchronized (this ) {
775
- if (inState (TransportState .SETUP )) {
776
- if (!authorization .isOk ()) {
777
- shutdownInternal (authorization , true );
778
- } else if (!setOutgoingBinder (OneWayBinderProxy .wrap (binder , offloadExecutor ))) {
779
- shutdownInternal (
780
- Status .UNAVAILABLE .withDescription ("Failed to observe outgoing binder" ), true );
781
- } else {
782
- // Check state again, since a failure inside setOutgoingBinder (or a callback it
783
- // triggers), could have shut us down.
784
- if (!isShutdown ()) {
785
- setState (TransportState .READY );
786
- attributes = clientTransportListener .filterTransport (attributes );
787
- clientTransportListener .transportReady ();
788
- if (readyTimeoutFuture != null ) {
789
- readyTimeoutFuture .cancel (false );
790
- readyTimeoutFuture = null ;
791
- }
778
+ private synchronized void handleAuthResult (IBinder binder , Status authorization ) {
779
+ if (inState (TransportState .SETUP )) {
780
+ if (!authorization .isOk ()) {
781
+ shutdownInternal (authorization , true );
782
+ } else if (!setOutgoingBinder (OneWayBinderProxy .wrap (binder , offloadExecutor ))) {
783
+ shutdownInternal (
784
+ Status .UNAVAILABLE .withDescription ("Failed to observe outgoing binder" ), true );
785
+ } else {
786
+ // Check state again, since a failure inside setOutgoingBinder (or a callback it
787
+ // triggers), could have shut us down.
788
+ if (!isShutdown ()) {
789
+ setState (TransportState .READY );
790
+ attributes = clientTransportListener .filterTransport (attributes );
791
+ clientTransportListener .transportReady ();
792
+ if (readyTimeoutFuture != null ) {
793
+ readyTimeoutFuture .cancel (false );
794
+ readyTimeoutFuture = null ;
792
795
}
793
796
}
794
797
}
795
798
}
796
799
}
797
800
801
+ private synchronized void handleAuthResult (Throwable t ) {
802
+ shutdownInternal (
803
+ Status .INTERNAL
804
+ .withDescription ("Could not evaluate SecurityPolicy" )
805
+ .withCause (t ),
806
+ true );
807
+ }
808
+
798
809
@ GuardedBy ("this" )
799
810
@ Override
800
811
protected void handlePingResponse (Parcel parcel ) {
0 commit comments