mirror of https://github.com/grpc/grpc-java.git
google-java-format binder/src/*/*.java (#11297)
https://github.com/grpc/grpc-java/blob/master/CONTRIBUTING.md#code-style We've been talking about an incremental approach in https://github.com/grpc/grpc-java/issues/1664 but https://github.com/google/google-java-format/issues/1114 causes a bunch of manual formatting toil every time I run ~/google-java-format-diff.py because we have a LOT of lines >100 characters. Establishing a gjf-clean baseline will make things a lot easier for me.
This commit is contained in:
parent
46e54aeb4b
commit
5770114d08
|
|
@ -78,8 +78,8 @@ public final class BinderChannelSmokeTest {
|
|||
private static final int SLIGHTLY_MORE_THAN_ONE_BLOCK = 16 * 1024 + 100;
|
||||
private static final String MSG = "Some text which will be repeated many many times";
|
||||
private static final String SERVER_TARGET_URI = "fake://server";
|
||||
private static final Metadata.Key<PoisonParcelable> POISON_KEY = ParcelableUtils.metadataKey(
|
||||
"poison-bin", PoisonParcelable.CREATOR);
|
||||
private static final Metadata.Key<PoisonParcelable> POISON_KEY =
|
||||
ParcelableUtils.metadataKey("poison-bin", PoisonParcelable.CREATOR);
|
||||
|
||||
final MethodDescriptor<String, String> method =
|
||||
MethodDescriptor.newBuilder(StringMarshaller.INSTANCE, StringMarshaller.INSTANCE)
|
||||
|
|
@ -140,22 +140,27 @@ public final class BinderChannelSmokeTest {
|
|||
AndroidComponentAddress serverAddress = HostServices.allocateService(appContext);
|
||||
fakeNameResolverProvider = new FakeNameResolverProvider(SERVER_TARGET_URI, serverAddress);
|
||||
NameResolverRegistry.getDefaultRegistry().register(fakeNameResolverProvider);
|
||||
HostServices.configureService(serverAddress,
|
||||
HostServices.configureService(
|
||||
serverAddress,
|
||||
HostServices.serviceParamsBuilder()
|
||||
.setServerFactory((service, receiver) ->
|
||||
BinderServerBuilder.forAddress(serverAddress, receiver)
|
||||
.inboundParcelablePolicy(InboundParcelablePolicy.newBuilder()
|
||||
.setAcceptParcelableMetadataValues(true)
|
||||
.setServerFactory(
|
||||
(service, receiver) ->
|
||||
BinderServerBuilder.forAddress(serverAddress, receiver)
|
||||
.inboundParcelablePolicy(
|
||||
InboundParcelablePolicy.newBuilder()
|
||||
.setAcceptParcelableMetadataValues(true)
|
||||
.build())
|
||||
.addService(serviceDef)
|
||||
.build())
|
||||
.addService(serviceDef)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
channel = BinderChannelBuilder.forAddress(serverAddress, appContext)
|
||||
.inboundParcelablePolicy(InboundParcelablePolicy.newBuilder()
|
||||
.setAcceptParcelableMetadataValues(true)
|
||||
.build())
|
||||
.build();
|
||||
channel =
|
||||
BinderChannelBuilder.forAddress(serverAddress, appContext)
|
||||
.inboundParcelablePolicy(
|
||||
InboundParcelablePolicy.newBuilder()
|
||||
.setAcceptParcelableMetadataValues(true)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
@ -253,8 +258,8 @@ public final class BinderChannelSmokeTest {
|
|||
Metadata extraHeadersToSend = new Metadata();
|
||||
extraHeadersToSend.put(POISON_KEY, bad);
|
||||
Channel interceptedChannel =
|
||||
ClientInterceptors.intercept(channel,
|
||||
MetadataUtils.newAttachHeadersInterceptor(extraHeadersToSend));
|
||||
ClientInterceptors.intercept(
|
||||
channel, MetadataUtils.newAttachHeadersInterceptor(extraHeadersToSend));
|
||||
CallOptions callOptions = CallOptions.DEFAULT.withDeadlineAfter(5, SECONDS);
|
||||
try {
|
||||
ClientCalls.blockingUnaryCall(interceptedChannel, method, callOptions, "hello");
|
||||
|
|
@ -361,33 +366,36 @@ public final class BinderChannelSmokeTest {
|
|||
|
||||
class AddParcelableServerInterceptor implements ServerInterceptor {
|
||||
@Override
|
||||
public <ReqT, RespT> Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||
Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||
return next.startCall(new SimpleForwardingServerCall<ReqT, RespT>(call) {
|
||||
@Override
|
||||
public void sendHeaders(Metadata headers) {
|
||||
if (parcelableForResponseHeaders != null) {
|
||||
headers.put(POISON_KEY, parcelableForResponseHeaders);
|
||||
}
|
||||
super.sendHeaders(headers);
|
||||
}
|
||||
}, headers);
|
||||
public <ReqT, RespT> Listener<ReqT> interceptCall(
|
||||
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||
return next.startCall(
|
||||
new SimpleForwardingServerCall<ReqT, RespT>(call) {
|
||||
@Override
|
||||
public void sendHeaders(Metadata headers) {
|
||||
if (parcelableForResponseHeaders != null) {
|
||||
headers.put(POISON_KEY, parcelableForResponseHeaders);
|
||||
}
|
||||
super.sendHeaders(headers);
|
||||
}
|
||||
},
|
||||
headers);
|
||||
}
|
||||
}
|
||||
|
||||
static class PoisonParcelable implements Parcelable {
|
||||
|
||||
public static final Creator<PoisonParcelable> CREATOR = new Parcelable.Creator<PoisonParcelable>() {
|
||||
@Override
|
||||
public PoisonParcelable createFromParcel(Parcel parcel) {
|
||||
throw new RuntimeException("ouch");
|
||||
}
|
||||
public static final Creator<PoisonParcelable> CREATOR =
|
||||
new Parcelable.Creator<PoisonParcelable>() {
|
||||
@Override
|
||||
public PoisonParcelable createFromParcel(Parcel parcel) {
|
||||
throw new RuntimeException("ouch");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PoisonParcelable[] newArray(int n) {
|
||||
return new PoisonParcelable[n];
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public PoisonParcelable[] newArray(int n) {
|
||||
return new PoisonParcelable[n];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
|
@ -395,7 +403,6 @@ public final class BinderChannelSmokeTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int flags) {
|
||||
}
|
||||
public void writeToParcel(Parcel parcel, int flags) {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
|
@ -111,15 +110,14 @@ public final class BinderSecurityTest {
|
|||
private void createChannel(ServerSecurityPolicy serverPolicy, SecurityPolicy channelPolicy)
|
||||
throws Exception {
|
||||
AndroidComponentAddress addr = HostServices.allocateService(appContext);
|
||||
HostServices.configureService(addr,
|
||||
HostServices.configureService(
|
||||
addr,
|
||||
HostServices.serviceParamsBuilder()
|
||||
.setServerFactory((service, receiver) -> buildServer(addr, receiver, serverPolicy))
|
||||
.build());
|
||||
.setServerFactory((service, receiver) -> buildServer(addr, receiver, serverPolicy))
|
||||
.build());
|
||||
|
||||
channel =
|
||||
BinderChannelBuilder.forAddress(addr, appContext)
|
||||
.securityPolicy(channelPolicy)
|
||||
.build();
|
||||
BinderChannelBuilder.forAddress(addr, appContext).securityPolicy(channelPolicy).build();
|
||||
}
|
||||
|
||||
private Server buildServer(
|
||||
|
|
@ -149,7 +147,7 @@ public final class BinderSecurityTest {
|
|||
try {
|
||||
ClientCalls.blockingUnaryCall(channel, method, CallOptions.DEFAULT, null);
|
||||
fail("Expected call to " + method.getFullMethodName() + " to fail but it succeeded.");
|
||||
throw new AssertionError(); // impossible
|
||||
throw new AssertionError(); // impossible
|
||||
} catch (StatusRuntimeException sre) {
|
||||
assertThat(sre.getStatus().getCode()).isEqualTo(status.getCode());
|
||||
return sre;
|
||||
|
|
@ -186,12 +184,14 @@ public final class BinderSecurityTest {
|
|||
IllegalStateException originalException = new IllegalStateException(errorMessage);
|
||||
createChannel(
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy("foo", new AsyncSecurityPolicy() {
|
||||
@Override
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
return Futures.immediateFailedFuture(originalException);
|
||||
}
|
||||
})
|
||||
.servicePolicy(
|
||||
"foo",
|
||||
new AsyncSecurityPolicy() {
|
||||
@Override
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
return Futures.immediateFailedFuture(originalException);
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
SecurityPolicies.internalOnly());
|
||||
MethodDescriptor<Empty, Empty> method = methods.get("foo/method0");
|
||||
|
|
@ -205,15 +205,17 @@ public final class BinderSecurityTest {
|
|||
AtomicReference<Boolean> firstAttempt = new AtomicReference<>(true);
|
||||
createChannel(
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy("foo", new AsyncSecurityPolicy() {
|
||||
@Override
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
if (firstAttempt.getAndSet(false)) {
|
||||
return Futures.immediateFailedFuture(new IllegalStateException());
|
||||
}
|
||||
return Futures.immediateFuture(Status.OK);
|
||||
}
|
||||
})
|
||||
.servicePolicy(
|
||||
"foo",
|
||||
new AsyncSecurityPolicy() {
|
||||
@Override
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
if (firstAttempt.getAndSet(false)) {
|
||||
return Futures.immediateFailedFuture(new IllegalStateException());
|
||||
}
|
||||
return Futures.immediateFuture(Status.OK);
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
SecurityPolicies.internalOnly());
|
||||
MethodDescriptor<Empty, Empty> method = methods.get("foo/method0");
|
||||
|
|
@ -227,15 +229,17 @@ public final class BinderSecurityTest {
|
|||
AtomicReference<Boolean> firstAttempt = new AtomicReference<>(true);
|
||||
createChannel(
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy("foo", new AsyncSecurityPolicy() {
|
||||
@Override
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
if (firstAttempt.getAndSet(false)) {
|
||||
return Futures.immediateCancelledFuture();
|
||||
}
|
||||
return Futures.immediateFuture(Status.OK);
|
||||
}
|
||||
})
|
||||
.servicePolicy(
|
||||
"foo",
|
||||
new AsyncSecurityPolicy() {
|
||||
@Override
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
if (firstAttempt.getAndSet(false)) {
|
||||
return Futures.immediateCancelledFuture();
|
||||
}
|
||||
return Futures.immediateFuture(Status.OK);
|
||||
}
|
||||
})
|
||||
.build(),
|
||||
SecurityPolicies.internalOnly());
|
||||
MethodDescriptor<Empty, Empty> method = methods.get("foo/method0");
|
||||
|
|
@ -275,11 +279,11 @@ public final class BinderSecurityTest {
|
|||
@Test
|
||||
public void testPerServicePolicyAsync() throws Exception {
|
||||
createChannel(
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy("foo", asyncPolicy((uid) -> Futures.immediateFuture(true)))
|
||||
.servicePolicy("bar", asyncPolicy((uid) -> Futures.immediateFuture(false)))
|
||||
.build(),
|
||||
SecurityPolicies.internalOnly());
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy("foo", asyncPolicy((uid) -> Futures.immediateFuture(true)))
|
||||
.servicePolicy("bar", asyncPolicy((uid) -> Futures.immediateFuture(false)))
|
||||
.build(),
|
||||
SecurityPolicies.internalOnly());
|
||||
|
||||
assertThat(methods).isNotEmpty();
|
||||
for (MethodDescriptor<Empty, Empty> method : methods.values()) {
|
||||
|
|
@ -326,11 +330,10 @@ public final class BinderSecurityTest {
|
|||
return new AsyncSecurityPolicy() {
|
||||
@Override
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
return Futures
|
||||
.transform(
|
||||
func.apply(uid),
|
||||
allowed -> allowed ? Status.OK : Status.PERMISSION_DENIED,
|
||||
MoreExecutors.directExecutor());
|
||||
return Futures.transform(
|
||||
func.apply(uid),
|
||||
allowed -> allowed ? Status.OK : Status.PERMISSION_DENIED,
|
||||
MoreExecutors.directExecutor());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -340,9 +343,7 @@ public final class BinderSecurityTest {
|
|||
|
||||
@Override
|
||||
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
|
||||
ServerCall<ReqT, RespT> call,
|
||||
Metadata headers,
|
||||
ServerCallHandler<ReqT, RespT> next) {
|
||||
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||
numInterceptedCalls += 1;
|
||||
return next.startCall(call, headers);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package io.grpc.binder;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
|
|
@ -30,20 +29,12 @@ import android.os.RemoteException;
|
|||
import androidx.lifecycle.LifecycleService;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import io.grpc.NameResolver;
|
||||
import io.grpc.Server;
|
||||
import io.grpc.ServerServiceDefinition;
|
||||
import io.grpc.ServerStreamTracer;
|
||||
import io.grpc.binder.AndroidComponentAddress;
|
||||
import io.grpc.internal.InternalServer;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
|
|
@ -64,7 +55,6 @@ public final class HostServices {
|
|||
HostService1.class, HostService2.class,
|
||||
};
|
||||
|
||||
|
||||
public interface ServerFactory {
|
||||
Server createServer(Service service, IBinderReceiver receiver);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,9 +80,8 @@ import org.junit.runner.RunWith;
|
|||
public final class BinderClientTransportTest {
|
||||
private static final long TIMEOUT_SECONDS = 5;
|
||||
|
||||
private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] {
|
||||
new ClientStreamTracer() {}
|
||||
};
|
||||
private static final ClientStreamTracer[] tracers =
|
||||
new ClientStreamTracer[] {new ClientStreamTracer() {}};
|
||||
|
||||
private final Context appContext = ApplicationProvider.getApplicationContext();
|
||||
|
||||
|
|
@ -149,10 +148,11 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
|
||||
private class BinderClientTransportBuilder {
|
||||
final BinderClientTransportFactory.Builder factoryBuilder = new BinderClientTransportFactory.Builder()
|
||||
.setSourceContext(appContext)
|
||||
.setScheduledExecutorPool(executorServicePool)
|
||||
.setOffloadExecutorPool(offloadServicePool);
|
||||
final BinderClientTransportFactory.Builder factoryBuilder =
|
||||
new BinderClientTransportFactory.Builder()
|
||||
.setSourceContext(appContext)
|
||||
.setScheduledExecutorPool(executorServicePool)
|
||||
.setOffloadExecutorPool(offloadServicePool);
|
||||
|
||||
public BinderClientTransportBuilder setSecurityPolicy(SecurityPolicy securityPolicy) {
|
||||
factoryBuilder.setSecurityPolicy(securityPolicy);
|
||||
|
|
@ -171,7 +171,8 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
|
||||
public BinderTransport.BinderClientTransport build() {
|
||||
return factoryBuilder.buildClientTransportFactory()
|
||||
return factoryBuilder
|
||||
.buildClientTransportFactory()
|
||||
.newClientTransport(serverAddress, new ClientTransportOptions(), null);
|
||||
}
|
||||
}
|
||||
|
|
@ -197,8 +198,8 @@ public final class BinderClientTransportTest {
|
|||
public void testShutdownBeforeStreamStart_b153326034() throws Exception {
|
||||
transport = new BinderClientTransportBuilder().build();
|
||||
startAndAwaitReady(transport, transportListener);
|
||||
ClientStream stream = transport.newStream(
|
||||
methodDesc, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||
ClientStream stream =
|
||||
transport.newStream(methodDesc, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||
transport.shutdownNow(Status.UNKNOWN.withDescription("reasons"));
|
||||
|
||||
// This shouldn't throw an exception.
|
||||
|
|
@ -284,7 +285,8 @@ public final class BinderClientTransportTest {
|
|||
@Test
|
||||
public void testNewStreamBeforeTransportReadyFails() throws Exception {
|
||||
// Use a special SecurityPolicy that lets us act before the transport is setup/ready.
|
||||
transport = new BinderClientTransportBuilder().setSecurityPolicy(blockingSecurityPolicy).build();
|
||||
transport =
|
||||
new BinderClientTransportBuilder().setSecurityPolicy(blockingSecurityPolicy).build();
|
||||
transport.start(transportListener).run();
|
||||
ClientStream stream =
|
||||
transport.newStream(streamingMethodDesc, new Metadata(), CallOptions.DEFAULT, tracers);
|
||||
|
|
@ -299,12 +301,10 @@ public final class BinderClientTransportTest {
|
|||
@Test
|
||||
public void testTxnFailureDuringSetup() throws Exception {
|
||||
BlockingBinderDecorator<ThrowingOneWayBinderProxy> decorator = new BlockingBinderDecorator<>();
|
||||
transport = new BinderClientTransportBuilder()
|
||||
.setBinderDecorator(decorator)
|
||||
.build();
|
||||
transport = new BinderClientTransportBuilder().setBinderDecorator(decorator).build();
|
||||
transport.start(transportListener).run();
|
||||
ThrowingOneWayBinderProxy endpointBinder = new ThrowingOneWayBinderProxy(
|
||||
decorator.takeNextRequest());
|
||||
ThrowingOneWayBinderProxy endpointBinder =
|
||||
new ThrowingOneWayBinderProxy(decorator.takeNextRequest());
|
||||
DeadObjectException doe = new DeadObjectException("ouch");
|
||||
endpointBinder.setRemoteException(doe);
|
||||
decorator.putNextResult(endpointBinder);
|
||||
|
|
@ -326,15 +326,13 @@ public final class BinderClientTransportTest {
|
|||
@Test
|
||||
public void testTxnFailurePostSetup() throws Exception {
|
||||
BlockingBinderDecorator<ThrowingOneWayBinderProxy> decorator = new BlockingBinderDecorator<>();
|
||||
transport = new BinderClientTransportBuilder()
|
||||
.setBinderDecorator(decorator)
|
||||
.build();
|
||||
transport = new BinderClientTransportBuilder().setBinderDecorator(decorator).build();
|
||||
transport.start(transportListener).run();
|
||||
ThrowingOneWayBinderProxy endpointBinder = new ThrowingOneWayBinderProxy(
|
||||
decorator.takeNextRequest());
|
||||
ThrowingOneWayBinderProxy endpointBinder =
|
||||
new ThrowingOneWayBinderProxy(decorator.takeNextRequest());
|
||||
decorator.putNextResult(endpointBinder);
|
||||
ThrowingOneWayBinderProxy serverBinder = new ThrowingOneWayBinderProxy(
|
||||
decorator.takeNextRequest());
|
||||
ThrowingOneWayBinderProxy serverBinder =
|
||||
new ThrowingOneWayBinderProxy(decorator.takeNextRequest());
|
||||
DeadObjectException doe = new DeadObjectException("ouch");
|
||||
serverBinder.setRemoteException(doe);
|
||||
decorator.putNextResult(serverBinder);
|
||||
|
|
@ -355,13 +353,14 @@ public final class BinderClientTransportTest {
|
|||
@Test
|
||||
public void testBlackHoleEndpointConnectTimeout() throws Exception {
|
||||
BlockingBinderDecorator<BlackHoleOneWayBinderProxy> decorator = new BlockingBinderDecorator<>();
|
||||
transport = new BinderClientTransportBuilder()
|
||||
.setBinderDecorator(decorator)
|
||||
.setReadyTimeoutMillis(1_234)
|
||||
.build();
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setBinderDecorator(decorator)
|
||||
.setReadyTimeoutMillis(1_234)
|
||||
.build();
|
||||
transport.start(transportListener).run();
|
||||
BlackHoleOneWayBinderProxy endpointBinder = new BlackHoleOneWayBinderProxy(
|
||||
decorator.takeNextRequest());
|
||||
BlackHoleOneWayBinderProxy endpointBinder =
|
||||
new BlackHoleOneWayBinderProxy(decorator.takeNextRequest());
|
||||
endpointBinder.dropAllTransactions(true);
|
||||
decorator.putNextResult(endpointBinder);
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
|
|
@ -372,10 +371,11 @@ public final class BinderClientTransportTest {
|
|||
|
||||
@Test
|
||||
public void testBlackHoleSecurityPolicyConnectTimeout() throws Exception {
|
||||
transport = new BinderClientTransportBuilder()
|
||||
.setSecurityPolicy(blockingSecurityPolicy)
|
||||
.setReadyTimeoutMillis(1_234)
|
||||
.build();
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setSecurityPolicy(blockingSecurityPolicy)
|
||||
.setReadyTimeoutMillis(1_234)
|
||||
.build();
|
||||
transport.start(transportListener).run();
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.DEADLINE_EXCEEDED);
|
||||
|
|
@ -387,9 +387,7 @@ public final class BinderClientTransportTest {
|
|||
@Test
|
||||
public void testAsyncSecurityPolicyFailure() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport = new BinderClientTransportBuilder()
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.build();
|
||||
transport = new BinderClientTransportBuilder().setSecurityPolicy(securityPolicy).build();
|
||||
RuntimeException exception = new NullPointerException();
|
||||
securityPolicy.setAuthorizationException(exception);
|
||||
transport.start(transportListener).run();
|
||||
|
|
@ -402,9 +400,7 @@ public final class BinderClientTransportTest {
|
|||
@Test
|
||||
public void testAsyncSecurityPolicySuccess() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport = new BinderClientTransportBuilder()
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.build();
|
||||
transport = new BinderClientTransportBuilder().setSecurityPolicy(securityPolicy).build();
|
||||
securityPolicy.setAuthorizationResult(Status.PERMISSION_DENIED);
|
||||
transport.start(transportListener).run();
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
|
|
@ -572,9 +568,7 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An AsyncSecurityPolicy that lets a test specify the outcome of checkAuthorizationAsync().
|
||||
*/
|
||||
/** An AsyncSecurityPolicy that lets a test specify the outcome of checkAuthorizationAsync(). */
|
||||
static class SettableAsyncSecurityPolicy extends AsyncSecurityPolicy {
|
||||
private SettableFuture<Status> result = SettableFuture.create();
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ public final class BinderTransportTest extends AbstractTransportTest {
|
|||
.setStreamTracerFactories(streamTracerFactories)
|
||||
.build();
|
||||
|
||||
HostServices.configureService(addr,
|
||||
HostServices.configureService(
|
||||
addr,
|
||||
HostServices.serviceParamsBuilder()
|
||||
.setRawBinderSupplier(() -> binderServer.getHostBinder())
|
||||
.build());
|
||||
|
|
@ -95,19 +96,18 @@ public final class BinderTransportTest extends AbstractTransportTest {
|
|||
@Override
|
||||
protected ManagedClientTransport newClientTransport(InternalServer server) {
|
||||
AndroidComponentAddress addr = (AndroidComponentAddress) server.getListenSocketAddress();
|
||||
BinderClientTransportFactory.Builder builder = new BinderClientTransportFactory.Builder()
|
||||
.setSourceContext(appContext)
|
||||
.setScheduledExecutorPool(executorServicePool)
|
||||
.setOffloadExecutorPool(offloadExecutorPool);
|
||||
BinderClientTransportFactory.Builder builder =
|
||||
new BinderClientTransportFactory.Builder()
|
||||
.setSourceContext(appContext)
|
||||
.setScheduledExecutorPool(executorServicePool)
|
||||
.setOffloadExecutorPool(offloadExecutorPool);
|
||||
|
||||
ClientTransportOptions options = new ClientTransportOptions();
|
||||
options.setEagAttributes(eagAttrs());
|
||||
options.setChannelLogger(transportLogger());
|
||||
|
||||
return new BinderTransport.BinderClientTransport(
|
||||
builder.buildClientTransportFactory(),
|
||||
addr,
|
||||
options);
|
||||
builder.buildClientTransportFactory(), addr, options);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -20,16 +20,14 @@ import java.util.concurrent.BlockingQueue;
|
|||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A collection of {@link OneWayBinderProxy}-related test helpers.
|
||||
*/
|
||||
/** A collection of {@link OneWayBinderProxy}-related test helpers. */
|
||||
public final class OneWayBinderProxies {
|
||||
/**
|
||||
* A {@link OneWayBinderProxy.Decorator} that blocks calling threads while an (external) test
|
||||
* provides the actual decoration.
|
||||
*/
|
||||
public static final class BlockingBinderDecorator<T extends OneWayBinderProxy> implements
|
||||
OneWayBinderProxy.Decorator {
|
||||
public static final class BlockingBinderDecorator<T extends OneWayBinderProxy>
|
||||
implements OneWayBinderProxy.Decorator {
|
||||
private final BlockingQueue<OneWayBinderProxy> requests = new LinkedBlockingQueue<>();
|
||||
private final BlockingQueue<T> results = new LinkedBlockingQueue<>();
|
||||
|
||||
|
|
@ -37,16 +35,14 @@ public final class OneWayBinderProxies {
|
|||
* Returns the next {@link OneWayBinderProxy} that needs decorating, blocking if it hasn't yet
|
||||
* been provided to {@link #decorate}.
|
||||
*
|
||||
* <p>Follow this with a call to {@link #putNextResult(OneWayBinderProxy)} to provide
|
||||
* the result of {@link #decorate} and unblock the waiting caller.
|
||||
* <p>Follow this with a call to {@link #putNextResult(OneWayBinderProxy)} to provide the result
|
||||
* of {@link #decorate} and unblock the waiting caller.
|
||||
*/
|
||||
public OneWayBinderProxy takeNextRequest() throws InterruptedException {
|
||||
return requests.take();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the next value to return from {@link #decorate}.
|
||||
*/
|
||||
/** Provides the next value to return from {@link #decorate}. */
|
||||
public void putNextResult(T next) throws InterruptedException {
|
||||
results.put(next);
|
||||
}
|
||||
|
|
@ -63,13 +59,10 @@ public final class OneWayBinderProxies {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link OneWayBinderProxy} decorator whose transact method can artificially throw.
|
||||
*/
|
||||
/** A {@link OneWayBinderProxy} decorator whose transact method can artificially throw. */
|
||||
public static final class ThrowingOneWayBinderProxy extends OneWayBinderProxy {
|
||||
private final OneWayBinderProxy wrapped;
|
||||
@Nullable
|
||||
private RemoteException remoteException;
|
||||
@Nullable private RemoteException remoteException;
|
||||
|
||||
ThrowingOneWayBinderProxy(OneWayBinderProxy wrapped) {
|
||||
super(wrapped.getDelegate());
|
||||
|
|
@ -127,5 +120,6 @@ public final class OneWayBinderProxies {
|
|||
}
|
||||
|
||||
// Cannot be instantiated.
|
||||
private OneWayBinderProxies() {};
|
||||
private OneWayBinderProxies() {}
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ public final class AndroidComponentAddress extends SocketAddress {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates an address referencing a {@link android.app.Service} in another
|
||||
* application and using the default binding {@link Intent}.
|
||||
* Creates an address referencing a {@link android.app.Service} in another application and using
|
||||
* the default binding {@link Intent}.
|
||||
*
|
||||
* @param applicationPackage The package name of the application containing the server.
|
||||
* @param serviceClassName The full class name of the Android Service to bind to.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package io.grpc.binder;
|
|||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import io.grpc.ExperimentalApi;
|
||||
import io.grpc.Status;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
|
@ -37,24 +36,24 @@ import javax.annotation.CheckReturnValue;
|
|||
@CheckReturnValue
|
||||
public abstract class AsyncSecurityPolicy extends SecurityPolicy {
|
||||
|
||||
/**
|
||||
* @deprecated Prefer {@link #checkAuthorizationAsync(int)} for async or slow calls or subclass
|
||||
* {@link SecurityPolicy} directly for quick, synchronous implementations.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public final Status checkAuthorization(int uid) {
|
||||
try {
|
||||
return checkAuthorizationAsync(uid).get();
|
||||
} catch (ExecutionException e) {
|
||||
return Status.fromThrowable(e);
|
||||
} catch (CancellationException e) {
|
||||
return Status.CANCELLED.withCause(e);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt(); // re-set the current thread's interruption state
|
||||
return Status.CANCELLED.withCause(e);
|
||||
/**
|
||||
* @deprecated Prefer {@link #checkAuthorizationAsync(int)} for async or slow calls or subclass
|
||||
* {@link SecurityPolicy} directly for quick, synchronous implementations.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public final Status checkAuthorization(int uid) {
|
||||
try {
|
||||
return checkAuthorizationAsync(uid).get();
|
||||
} catch (ExecutionException e) {
|
||||
return Status.fromThrowable(e);
|
||||
} catch (CancellationException e) {
|
||||
return Status.CANCELLED.withCause(e);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt(); // re-set the current thread's interruption state
|
||||
return Status.CANCELLED.withCause(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides whether the given Android UID is authorized. (Validity is implementation dependent).
|
||||
|
|
|
|||
|
|
@ -42,8 +42,7 @@ import javax.annotation.Nullable;
|
|||
* Services</a>
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/8022")
|
||||
public final class BinderChannelBuilder
|
||||
extends ForwardingChannelBuilder<BinderChannelBuilder> {
|
||||
public final class BinderChannelBuilder extends ForwardingChannelBuilder<BinderChannelBuilder> {
|
||||
|
||||
/**
|
||||
* Creates a channel builder that will bind to a remote Android service.
|
||||
|
|
@ -97,8 +96,8 @@ public final class BinderChannelBuilder
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a channel builder that will bind to a remote Android service, via a string
|
||||
* target name which will be resolved.
|
||||
* Creates a channel builder that will bind to a remote Android service, via a string target name
|
||||
* which will be resolved.
|
||||
*
|
||||
* <p>The underlying Android binding will be torn down when the channel becomes idle. This happens
|
||||
* after 30 minutes without use by default but can be configured via {@link
|
||||
|
|
@ -109,16 +108,13 @@ public final class BinderChannelBuilder
|
|||
* resulting builder. They will not be shut down automatically.
|
||||
*
|
||||
* @param target A target uri which should resolve into an {@link AndroidComponentAddress}
|
||||
* referencing the service to bind to.
|
||||
* referencing the service to bind to.
|
||||
* @param sourceContext the context to bind from (e.g. The current Activity or Application).
|
||||
* @return a new builder
|
||||
*/
|
||||
public static BinderChannelBuilder forTarget(String target, Context sourceContext) {
|
||||
return new BinderChannelBuilder(
|
||||
null,
|
||||
checkNotNull(target, "target"),
|
||||
sourceContext,
|
||||
BinderChannelCredentials.forDefault());
|
||||
null, checkNotNull(target, "target"), sourceContext, BinderChannelCredentials.forDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -147,18 +143,14 @@ public final class BinderChannelBuilder
|
|||
null, checkNotNull(target, "target"), sourceContext, channelCredentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Always fails. Call {@link #forAddress(AndroidComponentAddress, Context)} instead.
|
||||
*/
|
||||
/** Always fails. Call {@link #forAddress(AndroidComponentAddress, Context)} instead. */
|
||||
@DoNotCall("Unsupported. Use forAddress(AndroidComponentAddress, Context) instead")
|
||||
public static BinderChannelBuilder forAddress(String name, int port) {
|
||||
throw new UnsupportedOperationException(
|
||||
"call forAddress(AndroidComponentAddress, Context) instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* Always fails. Call {@link #forAddress(AndroidComponentAddress, Context)} instead.
|
||||
*/
|
||||
/** Always fails. Call {@link #forAddress(AndroidComponentAddress, Context)} instead. */
|
||||
@DoNotCall("Unsupported. Use forTarget(String, Context) instead")
|
||||
public static BinderChannelBuilder forTarget(String target) {
|
||||
throw new UnsupportedOperationException(
|
||||
|
|
@ -175,23 +167,18 @@ public final class BinderChannelBuilder
|
|||
@Nullable String target,
|
||||
Context sourceContext,
|
||||
BinderChannelCredentials channelCredentials) {
|
||||
transportFactoryBuilder = new BinderClientTransportFactory.Builder()
|
||||
.setSourceContext(sourceContext)
|
||||
.setChannelCredentials(channelCredentials);
|
||||
transportFactoryBuilder =
|
||||
new BinderClientTransportFactory.Builder()
|
||||
.setSourceContext(sourceContext)
|
||||
.setChannelCredentials(channelCredentials);
|
||||
|
||||
if (directAddress != null) {
|
||||
managedChannelImplBuilder =
|
||||
new ManagedChannelImplBuilder(
|
||||
directAddress,
|
||||
directAddress.getAuthority(),
|
||||
transportFactoryBuilder,
|
||||
null);
|
||||
directAddress, directAddress.getAuthority(), transportFactoryBuilder, null);
|
||||
} else {
|
||||
managedChannelImplBuilder =
|
||||
new ManagedChannelImplBuilder(
|
||||
target,
|
||||
transportFactoryBuilder,
|
||||
null);
|
||||
new ManagedChannelImplBuilder(target, transportFactoryBuilder, null);
|
||||
}
|
||||
idleTimeout(60, TimeUnit.SECONDS);
|
||||
}
|
||||
|
|
@ -218,7 +205,7 @@ public final class BinderChannelBuilder
|
|||
*/
|
||||
public BinderChannelBuilder scheduledExecutorService(
|
||||
ScheduledExecutorService scheduledExecutorService) {
|
||||
transportFactoryBuilder.setScheduledExecutorPool(
|
||||
transportFactoryBuilder.setScheduledExecutorPool(
|
||||
new FixedObjectPool<>(checkNotNull(scheduledExecutorService, "scheduledExecutorService")));
|
||||
return this;
|
||||
}
|
||||
|
|
@ -248,7 +235,7 @@ public final class BinderChannelBuilder
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Provides the target {@UserHandle} of the remote Android service.
|
||||
*
|
||||
* <p>When targetUserHandle is set, Context.bindServiceAsUser will used and additional Android
|
||||
|
|
@ -273,11 +260,10 @@ public final class BinderChannelBuilder
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the channel idle timeout and prevents it from being enabled. This
|
||||
* allows a centralized application method to configure the channel builder
|
||||
* and return it, without worrying about another part of the application
|
||||
* accidentally enabling the idle timeout.
|
||||
/**
|
||||
* Disables the channel idle timeout and prevents it from being enabled. This allows a centralized
|
||||
* application method to configure the channel builder and return it, without worrying about
|
||||
* another part of the application accidentally enabling the idle timeout.
|
||||
*/
|
||||
public BinderChannelBuilder strictLifecycleManagement() {
|
||||
strictLifecycleManagement = true;
|
||||
|
|
@ -287,7 +273,9 @@ public final class BinderChannelBuilder
|
|||
|
||||
@Override
|
||||
public BinderChannelBuilder idleTimeout(long value, TimeUnit unit) {
|
||||
checkState(!strictLifecycleManagement, "Idle timeouts are not supported when strict lifecycle management is enabled");
|
||||
checkState(
|
||||
!strictLifecycleManagement,
|
||||
"Idle timeouts are not supported when strict lifecycle management is enabled");
|
||||
super.idleTimeout(value, unit);
|
||||
return this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ public final class BinderChannelCredentials extends ChannelCredentials {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns the admin component to be specified with DevicePolicyManager
|
||||
* bindDeviceAdminServiceAsUser API.
|
||||
* bindDeviceAdminServiceAsUser API.
|
||||
*/
|
||||
@Nullable
|
||||
public ComponentName getDevicePolicyAdminComponentName() {
|
||||
|
|
|
|||
|
|
@ -20,26 +20,22 @@ import android.os.IBinder;
|
|||
import io.grpc.Internal;
|
||||
import io.grpc.binder.internal.BinderTransportSecurity;
|
||||
|
||||
/**
|
||||
* Helper class to expose IBinderReceiver methods for legacy internal builders.
|
||||
*/
|
||||
/** Helper class to expose IBinderReceiver methods for legacy internal builders. */
|
||||
@Internal
|
||||
public class BinderInternal {
|
||||
|
||||
/**
|
||||
* Sets the receiver's {@link IBinder} using {@link IBinderReceiver#set(IBinder)}.
|
||||
*/
|
||||
/** Sets the receiver's {@link IBinder} using {@link IBinderReceiver#set(IBinder)}. */
|
||||
public static void setIBinder(IBinderReceiver receiver, IBinder binder) {
|
||||
receiver.set(binder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link BinderTransportSecurity.ServerPolicyChecker} from a
|
||||
* {@link ServerSecurityPolicy}. This exposes to callers an interface to check security policies
|
||||
* without causing hard dependencies on a specific class.
|
||||
* Creates a {@link BinderTransportSecurity.ServerPolicyChecker} from a {@link
|
||||
* ServerSecurityPolicy}. This exposes to callers an interface to check security policies without
|
||||
* causing hard dependencies on a specific class.
|
||||
*/
|
||||
public static BinderTransportSecurity.ServerPolicyChecker createPolicyChecker(
|
||||
ServerSecurityPolicy securityPolicy) {
|
||||
ServerSecurityPolicy securityPolicy) {
|
||||
return securityPolicy::checkAuthorizationForServiceAsync;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,35 +30,29 @@ import io.grpc.binder.internal.BinderServer;
|
|||
import io.grpc.binder.internal.BinderTransportSecurity;
|
||||
import io.grpc.internal.FixedObjectPool;
|
||||
import io.grpc.internal.ServerImplBuilder;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* Builder for a server that services requests from an Android Service.
|
||||
*/
|
||||
public final class BinderServerBuilder
|
||||
extends ForwardingServerBuilder<BinderServerBuilder> {
|
||||
/** Builder for a server that services requests from an Android Service. */
|
||||
public final class BinderServerBuilder extends ForwardingServerBuilder<BinderServerBuilder> {
|
||||
|
||||
/**
|
||||
* Creates a server builder that will listen for bindings to the specified address.
|
||||
*
|
||||
* <p>The listening {@link IBinder} associated with new {@link Server}s will be stored
|
||||
* in {@code binderReceiver} upon {@link #build()}. Callers should return it from {@link
|
||||
* <p>The listening {@link IBinder} associated with new {@link Server}s will be stored in {@code
|
||||
* binderReceiver} upon {@link #build()}. Callers should return it from {@link
|
||||
* Service#onBind(Intent)} when the binding intent matches {@code listenAddress}.
|
||||
*
|
||||
* @param listenAddress an Android Service and binding Intent associated with this server.
|
||||
* @param receiver an "out param" for the new {@link Server}'s listening {@link IBinder}
|
||||
* @return a new builder
|
||||
*/
|
||||
public static BinderServerBuilder forAddress(AndroidComponentAddress listenAddress,
|
||||
IBinderReceiver receiver) {
|
||||
public static BinderServerBuilder forAddress(
|
||||
AndroidComponentAddress listenAddress, IBinderReceiver receiver) {
|
||||
return new BinderServerBuilder(listenAddress, receiver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Always fails. Call {@link #forAddress(AndroidComponentAddress, IBinderReceiver)} instead.
|
||||
*/
|
||||
/** Always fails. Call {@link #forAddress(AndroidComponentAddress, IBinderReceiver)} instead. */
|
||||
@DoNotCall("Unsupported. Use forAddress() instead")
|
||||
public static BinderServerBuilder forPort(int port) {
|
||||
throw new UnsupportedOperationException("call forAddress() instead");
|
||||
|
|
@ -69,16 +63,17 @@ public final class BinderServerBuilder
|
|||
private boolean isBuilt;
|
||||
|
||||
private BinderServerBuilder(
|
||||
AndroidComponentAddress listenAddress,
|
||||
IBinderReceiver binderReceiver) {
|
||||
AndroidComponentAddress listenAddress, IBinderReceiver binderReceiver) {
|
||||
internalBuilder.setListenAddress(listenAddress);
|
||||
|
||||
serverImplBuilder = new ServerImplBuilder(streamTracerFactories -> {
|
||||
internalBuilder.setStreamTracerFactories(streamTracerFactories);
|
||||
BinderServer server = internalBuilder.build();
|
||||
BinderInternal.setIBinder(binderReceiver, server.getHostBinder());
|
||||
return server;
|
||||
});
|
||||
serverImplBuilder =
|
||||
new ServerImplBuilder(
|
||||
streamTracerFactories -> {
|
||||
internalBuilder.setStreamTracerFactories(streamTracerFactories);
|
||||
BinderServer server = internalBuilder.build();
|
||||
BinderInternal.setIBinder(binderReceiver, server.getHostBinder());
|
||||
return server;
|
||||
});
|
||||
|
||||
// Disable stats and tracing by default.
|
||||
serverImplBuilder.setStatsEnabled(false);
|
||||
|
|
@ -114,8 +109,8 @@ public final class BinderServerBuilder
|
|||
*/
|
||||
public BinderServerBuilder scheduledExecutorService(
|
||||
ScheduledExecutorService scheduledExecutorService) {
|
||||
internalBuilder.setExecutorServicePool(
|
||||
new FixedObjectPool<>(checkNotNull(scheduledExecutorService, "scheduledExecutorService")));
|
||||
internalBuilder.setExecutorServicePool(
|
||||
new FixedObjectPool<>(checkNotNull(scheduledExecutorService, "scheduledExecutorService")));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -140,9 +135,7 @@ public final class BinderServerBuilder
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always fails. TLS is not supported in BinderServer.
|
||||
*/
|
||||
/** Always fails. TLS is not supported in BinderServer. */
|
||||
@Override
|
||||
public BinderServerBuilder useTransportSecurity(File certChain, File privateKey) {
|
||||
throw new UnsupportedOperationException("TLS not supported in BinderServer");
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ public final class ParcelableUtils {
|
|||
*/
|
||||
public static <P extends Parcelable> Metadata.Key<P> metadataKeyForImmutableType(
|
||||
String name, Parcelable.Creator<P> creator) {
|
||||
return Metadata.Key.of(
|
||||
name, new MetadataHelper.ParcelableMetadataMarshaller<P>(creator, true));
|
||||
return Metadata.Key.of(name, new MetadataHelper.ParcelableMetadataMarshaller<P>(creator, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,4 +75,4 @@ public final class PeerUid {
|
|||
public String toString() {
|
||||
return "PeerUid{" + uid + '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,4 +100,4 @@ public final class PeerUids {
|
|||
}
|
||||
|
||||
private PeerUids() {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ public final class SecurityPolicies {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SecurityPolicy} which checks if the package signature
|
||||
* matches {@code requiredSignature}.
|
||||
* Creates a {@link SecurityPolicy} which checks if the package signature matches {@code
|
||||
* requiredSignature}.
|
||||
*
|
||||
* @param packageName the package name of the allowed package.
|
||||
* @param requiredSignature the allowed signature of the allowed package.
|
||||
|
|
@ -93,8 +93,7 @@ public final class SecurityPolicies {
|
|||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/8022")
|
||||
public static SecurityPolicy hasSignature(
|
||||
PackageManager packageManager, String packageName, Signature requiredSignature) {
|
||||
return oneOfSignatures(
|
||||
packageManager, packageName, ImmutableList.of(requiredSignature));
|
||||
return oneOfSignatures(packageManager, packageName, ImmutableList.of(requiredSignature));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,8 +113,8 @@ public final class SecurityPolicies {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link SecurityPolicy} which checks if the package signature
|
||||
* matches any of {@code requiredSignatures}.
|
||||
* Creates a {@link SecurityPolicy} which checks if the package signature matches any of {@code
|
||||
* requiredSignatures}.
|
||||
*
|
||||
* @param packageName the package name of the allowed package.
|
||||
* @param requiredSignatures the allowed signatures of the allowed package.
|
||||
|
|
@ -124,14 +123,11 @@ public final class SecurityPolicies {
|
|||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/8022")
|
||||
public static SecurityPolicy oneOfSignatures(
|
||||
PackageManager packageManager,
|
||||
String packageName,
|
||||
Collection<Signature> requiredSignatures) {
|
||||
PackageManager packageManager, String packageName, Collection<Signature> requiredSignatures) {
|
||||
Preconditions.checkNotNull(packageManager, "packageManager");
|
||||
Preconditions.checkNotNull(packageName, "packageName");
|
||||
Preconditions.checkNotNull(requiredSignatures, "requiredSignatures");
|
||||
Preconditions.checkArgument(!requiredSignatures.isEmpty(),
|
||||
"requiredSignatures");
|
||||
Preconditions.checkArgument(!requiredSignatures.isEmpty(), "requiredSignatures");
|
||||
ImmutableList<Signature> requiredSignaturesImmutable = ImmutableList.copyOf(requiredSignatures);
|
||||
|
||||
for (Signature requiredSignature : requiredSignaturesImmutable) {
|
||||
|
|
@ -141,8 +137,7 @@ public final class SecurityPolicies {
|
|||
return new SecurityPolicy() {
|
||||
@Override
|
||||
public Status checkAuthorization(int uid) {
|
||||
return checkUidSignature(
|
||||
packageManager, uid, packageName, requiredSignaturesImmutable);
|
||||
return checkUidSignature(packageManager, uid, packageName, requiredSignaturesImmutable);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -186,22 +181,23 @@ public final class SecurityPolicies {
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates {@link SecurityPolicy} which checks if the app is a device owner app. See
|
||||
* {@link DevicePolicyManager}.
|
||||
* Creates {@link SecurityPolicy} which checks if the app is a device owner app. See {@link
|
||||
* DevicePolicyManager}.
|
||||
*/
|
||||
@RequiresApi(18)
|
||||
public static io.grpc.binder.SecurityPolicy isDeviceOwner(Context applicationContext) {
|
||||
DevicePolicyManager devicePolicyManager =
|
||||
(DevicePolicyManager) applicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
return anyPackageWithUidSatisfies(
|
||||
applicationContext, pkg -> devicePolicyManager.isDeviceOwnerApp(pkg),
|
||||
applicationContext,
|
||||
pkg -> devicePolicyManager.isDeviceOwnerApp(pkg),
|
||||
"Rejected by device owner policy. No packages found for UID.",
|
||||
"Rejected by device owner policy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates {@link SecurityPolicy} which checks if the app is a profile owner app. See
|
||||
* {@link DevicePolicyManager}.
|
||||
* Creates {@link SecurityPolicy} which checks if the app is a profile owner app. See {@link
|
||||
* DevicePolicyManager}.
|
||||
*/
|
||||
@RequiresApi(21)
|
||||
public static SecurityPolicy isProfileOwner(Context applicationContext) {
|
||||
|
|
@ -223,9 +219,10 @@ public final class SecurityPolicies {
|
|||
(DevicePolicyManager) applicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
return anyPackageWithUidSatisfies(
|
||||
applicationContext,
|
||||
pkg -> VERSION.SDK_INT >= 30
|
||||
&& devicePolicyManager.isProfileOwnerApp(pkg)
|
||||
&& devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile(),
|
||||
pkg ->
|
||||
VERSION.SDK_INT >= 30
|
||||
&& devicePolicyManager.isProfileOwnerApp(pkg)
|
||||
&& devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile(),
|
||||
"Rejected by profile owner on organization-owned device policy. No packages found for UID.",
|
||||
"Rejected by profile owner on organization-owned device policy");
|
||||
}
|
||||
|
|
@ -237,8 +234,7 @@ public final class SecurityPolicies {
|
|||
ImmutableList<Signature> requiredSignatures) {
|
||||
String[] packages = packageManager.getPackagesForUid(uid);
|
||||
if (packages == null) {
|
||||
return Status.UNAUTHENTICATED.withDescription(
|
||||
"Rejected by signature check security policy");
|
||||
return Status.UNAUTHENTICATED.withDescription("Rejected by signature check security policy");
|
||||
}
|
||||
boolean packageNameMatched = false;
|
||||
for (String pkg : packages) {
|
||||
|
|
@ -251,8 +247,7 @@ public final class SecurityPolicies {
|
|||
}
|
||||
}
|
||||
return Status.PERMISSION_DENIED.withDescription(
|
||||
"Rejected by signature check security policy. Package name matched: "
|
||||
+ packageNameMatched);
|
||||
"Rejected by signature check security policy. Package name matched: " + packageNameMatched);
|
||||
}
|
||||
|
||||
private static Status checkUidSha256Signature(
|
||||
|
|
@ -289,9 +284,8 @@ public final class SecurityPolicies {
|
|||
*
|
||||
* @param packageName the package to be checked
|
||||
* @param signatureCheckFunction {@link Predicate} that takes a signature and verifies if it
|
||||
* satisfies any signature constraints
|
||||
* return {@code true} if {@code packageName} has a signature that satisfies {@code
|
||||
* signatureCheckFunction}.
|
||||
* satisfies any signature constraints return {@code true} if {@code packageName} has a
|
||||
* signature that satisfies {@code signatureCheckFunction}.
|
||||
*/
|
||||
@SuppressWarnings("deprecation") // For PackageInfo.signatures
|
||||
@SuppressLint("PackageManagerGetSignatures") // We only allow 1 signature.
|
||||
|
|
@ -423,23 +417,23 @@ public final class SecurityPolicies {
|
|||
/**
|
||||
* Creates a {@link SecurityPolicy} which checks if the caller has all of the given permissions
|
||||
* from {@code permissions}.
|
||||
*
|
||||
*
|
||||
* <p>The gRPC framework assumes that a {@link SecurityPolicy}'s verdict for a given peer UID will
|
||||
* not change over the lifetime of any process with that UID. But Android runtime permissions can
|
||||
* be granted or revoked by the user at any time and so using the {@link #hasPermissions}
|
||||
* {@link SecurityPolicy} comes with certain special responsibilities.
|
||||
*
|
||||
* <p>In particular, callers must ensure that the *subjects* of the returned
|
||||
* {@link SecurityPolicy} hold all required {@code permissions} *before* making use of it. Android
|
||||
* kills an app's processes when it loses any permission but the same isn't true when a permission
|
||||
* is granted. And so without special care, a {@link #hasPermissions} denial could incorrectly
|
||||
* be granted or revoked by the user at any time and so using the {@link #hasPermissions} {@link
|
||||
* SecurityPolicy} comes with certain special responsibilities.
|
||||
*
|
||||
* <p>In particular, callers must ensure that the *subjects* of the returned {@link
|
||||
* SecurityPolicy} hold all required {@code permissions} *before* making use of it. Android kills
|
||||
* an app's processes when it loses any permission but the same isn't true when a permission is
|
||||
* granted. And so without special care, a {@link #hasPermissions} denial could incorrectly
|
||||
* persist even if the subject is later granted all required {@code permissions}.
|
||||
*
|
||||
*
|
||||
* <p>A server using {@link #hasPermissions} must, as part of its RPC API contract, require
|
||||
* clients to request and receive all {@code permissions} before making a call. This is in line
|
||||
* with official Android guidance to request and confirm receipt of runtime permissions before
|
||||
* using them.
|
||||
*
|
||||
* using them.
|
||||
*
|
||||
* <p>A client, on the other hand, should only use {@link #hasPermissions} policies that require
|
||||
* install-time permissions which cannot change.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ import javax.annotation.CheckReturnValue;
|
|||
/**
|
||||
* Decides whether a given Android UID is authorized to access some resource.
|
||||
*
|
||||
* While it's possible to extend this class to define your own policy, it's strongly
|
||||
* recommended that you only use the policies provided by the {@link SecurityPolicies} or
|
||||
* {@link UntrustedSecurityPolicies} classes. Implementing your own security policy requires
|
||||
* significant care, and an understanding of the details and pitfalls of Android security.
|
||||
* <p>While it's possible to extend this class to define your own policy, it's strongly recommended
|
||||
* that you only use the policies provided by the {@link SecurityPolicies} or {@link
|
||||
* UntrustedSecurityPolicies} classes. Implementing your own security policy requires significant
|
||||
* care, and an understanding of the details and pitfalls of Android security.
|
||||
*
|
||||
* <p><b>IMPORTANT</b> For any concrete extensions of this class, it's assumed that the
|
||||
* authorization status of a given UID will <b>not</b> change as long as a process with that UID is
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import javax.annotation.CheckReturnValue;
|
|||
/**
|
||||
* A security policy for a gRPC server.
|
||||
*
|
||||
* Contains a default policy, and optional policies for each server.
|
||||
* <p>Contains a default policy, and optional policies for each server.
|
||||
*/
|
||||
public final class ServerSecurityPolicy {
|
||||
|
||||
|
|
@ -61,8 +61,8 @@ public final class ServerSecurityPolicy {
|
|||
/**
|
||||
* Returns whether the given Android UID is authorized to access a particular service.
|
||||
*
|
||||
* <p>This method never throws an exception. If the execution of the security policy check
|
||||
* fails, a failed future with such exception is returned.
|
||||
* <p>This method never throws an exception. If the execution of the security policy check fails,
|
||||
* a failed future with such exception is returned.
|
||||
*
|
||||
* @param uid The Android UID to authenticate.
|
||||
* @param serviceName The name of the gRPC service being called.
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ import io.grpc.ExperimentalApi;
|
|||
import io.grpc.Status;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
/**
|
||||
* Static factory methods for creating untrusted security policies.
|
||||
*/
|
||||
/** Static factory methods for creating untrusted security policies. */
|
||||
@CheckReturnValue
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/8022")
|
||||
public final class UntrustedSecurityPolicies {
|
||||
|
|
@ -30,11 +28,9 @@ public final class UntrustedSecurityPolicies {
|
|||
private UntrustedSecurityPolicies() {}
|
||||
|
||||
/**
|
||||
* Return a security policy which allows any peer on device.
|
||||
* Servers should only use this policy if they intend to expose
|
||||
* a service to all applications on device.
|
||||
* Clients should only use this policy if they don't need to trust the
|
||||
* application they're connecting to.
|
||||
* Return a security policy which allows any peer on device. Servers should only use this policy
|
||||
* if they intend to expose a service to all applications on device. Clients should only use this
|
||||
* policy if they don't need to trust the application they're connecting to.
|
||||
*/
|
||||
public static SecurityPolicy untrustedPublic() {
|
||||
return new SecurityPolicy() {
|
||||
|
|
|
|||
|
|
@ -41,9 +41,7 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Creates new binder transports.
|
||||
*/
|
||||
/** Creates new binder transports. */
|
||||
@Internal
|
||||
public final class BinderClientTransportFactory implements ClientTransportFactory {
|
||||
final Context sourceContext;
|
||||
|
|
@ -52,8 +50,7 @@ public final class BinderClientTransportFactory implements ClientTransportFactor
|
|||
final ObjectPool<ScheduledExecutorService> scheduledExecutorPool;
|
||||
final ObjectPool<? extends Executor> offloadExecutorPool;
|
||||
final SecurityPolicy securityPolicy;
|
||||
@Nullable
|
||||
final UserHandle targetUserHandle;
|
||||
@Nullable final UserHandle targetUserHandle;
|
||||
final BindServiceFlags bindServiceFlags;
|
||||
final InboundParcelablePolicy inboundParcelablePolicy;
|
||||
final OneWayBinderProxy.Decorator binderDecorator;
|
||||
|
|
@ -66,8 +63,10 @@ public final class BinderClientTransportFactory implements ClientTransportFactor
|
|||
private BinderClientTransportFactory(Builder builder) {
|
||||
sourceContext = checkNotNull(builder.sourceContext);
|
||||
channelCredentials = checkNotNull(builder.channelCredentials);
|
||||
mainThreadExecutor = builder.mainThreadExecutor != null ?
|
||||
builder.mainThreadExecutor : ContextCompat.getMainExecutor(sourceContext);
|
||||
mainThreadExecutor =
|
||||
builder.mainThreadExecutor != null
|
||||
? builder.mainThreadExecutor
|
||||
: ContextCompat.getMainExecutor(sourceContext);
|
||||
scheduledExecutorPool = checkNotNull(builder.scheduledExecutorPool);
|
||||
offloadExecutorPool = checkNotNull(builder.offloadExecutorPool);
|
||||
securityPolicy = checkNotNull(builder.securityPolicy);
|
||||
|
|
@ -112,9 +111,7 @@ public final class BinderClientTransportFactory implements ClientTransportFactor
|
|||
return Collections.singleton(AndroidComponentAddress.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows fluent construction of ClientTransportFactory.
|
||||
*/
|
||||
/** Allows fluent construction of ClientTransportFactory. */
|
||||
public static final class Builder implements ClientTransportFactoryBuilder {
|
||||
// Required.
|
||||
Context sourceContext;
|
||||
|
|
@ -122,16 +119,15 @@ public final class BinderClientTransportFactory implements ClientTransportFactor
|
|||
|
||||
// Optional.
|
||||
BinderChannelCredentials channelCredentials = BinderChannelCredentials.forDefault();
|
||||
Executor mainThreadExecutor; // Default filled-in at build time once sourceContext is decided.
|
||||
Executor mainThreadExecutor; // Default filled-in at build time once sourceContext is decided.
|
||||
ObjectPool<ScheduledExecutorService> scheduledExecutorPool =
|
||||
SharedResourcePool.forResource(GrpcUtil.TIMER_SERVICE);
|
||||
SecurityPolicy securityPolicy = SecurityPolicies.internalOnly();
|
||||
@Nullable
|
||||
UserHandle targetUserHandle;
|
||||
@Nullable UserHandle targetUserHandle;
|
||||
BindServiceFlags bindServiceFlags = BindServiceFlags.DEFAULTS;
|
||||
InboundParcelablePolicy inboundParcelablePolicy = InboundParcelablePolicy.DEFAULT;
|
||||
OneWayBinderProxy.Decorator binderDecorator = OneWayBinderProxy.IDENTITY_DECORATOR;
|
||||
long readyTimeoutMillis = -1; // TODO(jdcormie) Set an non-infinite default in a separate PR.
|
||||
long readyTimeoutMillis = -1; // TODO(jdcormie) Set an non-infinite default in a separate PR.
|
||||
|
||||
@Override
|
||||
public BinderClientTransportFactory buildClientTransportFactory() {
|
||||
|
|
@ -143,8 +139,7 @@ public final class BinderClientTransportFactory implements ClientTransportFactor
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setOffloadExecutorPool(
|
||||
ObjectPool<? extends Executor> offloadExecutorPool) {
|
||||
public Builder setOffloadExecutorPool(ObjectPool<? extends Executor> offloadExecutorPool) {
|
||||
this.offloadExecutorPool = checkNotNull(offloadExecutorPool, "offloadExecutorPool");
|
||||
return this;
|
||||
}
|
||||
|
|
@ -181,7 +176,8 @@ public final class BinderClientTransportFactory implements ClientTransportFactor
|
|||
}
|
||||
|
||||
public Builder setInboundParcelablePolicy(InboundParcelablePolicy inboundParcelablePolicy) {
|
||||
this.inboundParcelablePolicy = checkNotNull(inboundParcelablePolicy, "inboundParcelablePolicy");
|
||||
this.inboundParcelablePolicy =
|
||||
checkNotNull(inboundParcelablePolicy, "inboundParcelablePolicy");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -199,20 +195,20 @@ public final class BinderClientTransportFactory implements ClientTransportFactor
|
|||
* Limits how long it can take to for a new transport to become ready after being started.
|
||||
*
|
||||
* <p>This process currently includes:
|
||||
*
|
||||
* <ul>
|
||||
* <li>Creating an Android binding.
|
||||
* <li>Waiting for Android to create the server process.
|
||||
* <li>Waiting for the remote Service to be created and handle onBind().
|
||||
* <li>Exchanging handshake transactions according to the wire protocol.
|
||||
* <li>Evaluating a {@link SecurityPolicy} on both sides.
|
||||
* <li>Creating an Android binding.
|
||||
* <li>Waiting for Android to create the server process.
|
||||
* <li>Waiting for the remote Service to be created and handle onBind().
|
||||
* <li>Exchanging handshake transactions according to the wire protocol.
|
||||
* <li>Evaluating a {@link SecurityPolicy} on both sides.
|
||||
* </ul>
|
||||
*
|
||||
* <p>This setting doesn't change the need for deadlines at the call level. It merely ensures
|
||||
* that gRPC features like
|
||||
* <a href="https://github.com/grpc/grpc/blob/master/doc/load-balancing.md">load balancing</a>
|
||||
* and <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">fail-fast</a>
|
||||
* work as expected despite certain edge cases that could otherwise stall the transport
|
||||
* indefinitely.
|
||||
* that gRPC features like <a
|
||||
* href="https://github.com/grpc/grpc/blob/master/doc/load-balancing.md">load balancing</a> and
|
||||
* <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">fail-fast</a> work
|
||||
* as expected despite certain edge cases that could otherwise stall the transport indefinitely.
|
||||
*
|
||||
* <p>Optional. Use a negative value to wait indefinitely.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||
*
|
||||
* <p>Multiple incoming connections transports may be active at a time.
|
||||
*
|
||||
* <b>IMPORTANT</b>: This implementation must comply with this published wire format.
|
||||
* <p><b>IMPORTANT</b>: This implementation must comply with this published wire format.
|
||||
* https://github.com/grpc/proposal/blob/master/L73-java-binderchannel/wireformat.md
|
||||
*/
|
||||
@ThreadSafe
|
||||
|
|
@ -180,7 +180,9 @@ public final class BinderServer implements InternalServer, LeakSafeOneWayBinder.
|
|||
// Create a new transport and let our listener know about it.
|
||||
BinderTransport.BinderServerTransport transport =
|
||||
new BinderTransport.BinderServerTransport(
|
||||
executorServicePool, attrsBuilder.build(), streamTracerFactories,
|
||||
executorServicePool,
|
||||
attrsBuilder.build(),
|
||||
streamTracerFactories,
|
||||
OneWayBinderProxy.IDENTITY_DECORATOR,
|
||||
callbackBinder);
|
||||
transport.setServerTransportListener(listener.transportCreated(transport));
|
||||
|
|
@ -246,7 +248,8 @@ public final class BinderServer implements InternalServer, LeakSafeOneWayBinder.
|
|||
*
|
||||
* <p>Required.
|
||||
*/
|
||||
public Builder setStreamTracerFactories(List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
|
||||
public Builder setStreamTracerFactories(
|
||||
List<? extends ServerStreamTracer.Factory> streamTracerFactories) {
|
||||
this.streamTracerFactories = streamTracerFactories;
|
||||
return this;
|
||||
}
|
||||
|
|
@ -275,7 +278,7 @@ public final class BinderServer implements InternalServer, LeakSafeOneWayBinder.
|
|||
/**
|
||||
* Sets the {@link ServerSecurityPolicy} to be used for built servers.
|
||||
*
|
||||
* Optional, {@link SecurityPolicies#serverInternalOnly()} is the default.
|
||||
* <p>Optional, {@link SecurityPolicies#serverInternalOnly()} is the default.
|
||||
*/
|
||||
public Builder setServerSecurityPolicy(ServerSecurityPolicy serverSecurityPolicy) {
|
||||
this.serverSecurityPolicy = checkNotNull(serverSecurityPolicy, "serverSecurityPolicy");
|
||||
|
|
@ -285,10 +288,11 @@ public final class BinderServer implements InternalServer, LeakSafeOneWayBinder.
|
|||
/**
|
||||
* Sets the {@link InboundParcelablePolicy} to be used for built servers.
|
||||
*
|
||||
* Optional, {@link InboundParcelablePolicy#DEFAULT} is the default.
|
||||
* <p>Optional, {@link InboundParcelablePolicy#DEFAULT} is the default.
|
||||
*/
|
||||
public Builder setInboundParcelablePolicy(InboundParcelablePolicy inboundParcelablePolicy) {
|
||||
this.inboundParcelablePolicy = checkNotNull(inboundParcelablePolicy, "inboundParcelablePolicy");
|
||||
this.inboundParcelablePolicy =
|
||||
checkNotNull(inboundParcelablePolicy, "inboundParcelablePolicy");
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,12 +134,10 @@ public abstract class BinderTransport
|
|||
* <p>Should this change, we should still endeavor to support earlier wire-format versions. If
|
||||
* that's not possible, {@link EARLIEST_SUPPORTED_WIRE_FORMAT_VERSION} should be updated below.
|
||||
*/
|
||||
@Internal
|
||||
public static final int WIRE_FORMAT_VERSION = 1;
|
||||
@Internal public static final int WIRE_FORMAT_VERSION = 1;
|
||||
|
||||
/** The version code of the earliest wire format we support. */
|
||||
@Internal
|
||||
public static final int EARLIEST_SUPPORTED_WIRE_FORMAT_VERSION = 1;
|
||||
@Internal public static final int EARLIEST_SUPPORTED_WIRE_FORMAT_VERSION = 1;
|
||||
|
||||
/** The max number of "in-flight" bytes before we start buffering transactions. */
|
||||
private static final int TRANSACTION_BYTES_WINDOW = 128 * 1024;
|
||||
|
|
@ -152,12 +150,10 @@ public abstract class BinderTransport
|
|||
* the binder. and from the host s Followed by: int wire_protocol_version IBinder
|
||||
* client_transports_callback_binder
|
||||
*/
|
||||
@Internal
|
||||
public static final int SETUP_TRANSPORT = IBinder.FIRST_CALL_TRANSACTION;
|
||||
@Internal public static final int SETUP_TRANSPORT = IBinder.FIRST_CALL_TRANSACTION;
|
||||
|
||||
/** Send to shutdown the transport from either end. */
|
||||
@Internal
|
||||
public static final int SHUTDOWN_TRANSPORT = IBinder.FIRST_CALL_TRANSACTION + 1;
|
||||
@Internal public static final int SHUTDOWN_TRANSPORT = IBinder.FIRST_CALL_TRANSACTION + 1;
|
||||
|
||||
/** Send to acknowledge receipt of rpc bytes, for flow control. */
|
||||
static final int ACKNOWLEDGE_BYTES = IBinder.FIRST_CALL_TRANSACTION + 2;
|
||||
|
|
@ -329,7 +325,7 @@ public abstract class BinderTransport
|
|||
}
|
||||
synchronized (this) {
|
||||
notifyTerminated();
|
||||
}
|
||||
}
|
||||
releaseExecutors();
|
||||
});
|
||||
}
|
||||
|
|
@ -432,8 +428,8 @@ public abstract class BinderTransport
|
|||
try {
|
||||
return handleTransactionInternal(code, parcel);
|
||||
} catch (RuntimeException e) {
|
||||
logger.log(Level.SEVERE,
|
||||
"Terminating transport for uncaught Exception in transaction " + code, e);
|
||||
logger.log(
|
||||
Level.SEVERE, "Terminating transport for uncaught Exception in transaction " + code, e);
|
||||
synchronized (this) {
|
||||
// This unhandled exception may have put us in an inconsistent state. Force terminate the
|
||||
// whole transport so our peer knows something is wrong and so that clients can retry with
|
||||
|
|
@ -567,8 +563,10 @@ public abstract class BinderTransport
|
|||
private final Executor offloadExecutor;
|
||||
private final SecurityPolicy securityPolicy;
|
||||
private final Bindable serviceBinding;
|
||||
|
||||
/** Number of ongoing calls which keep this transport "in-use". */
|
||||
private final AtomicInteger numInUseStreams;
|
||||
|
||||
private final long readyTimeoutMillis;
|
||||
private final PingTracker pingTracker;
|
||||
|
||||
|
|
@ -576,6 +574,7 @@ public abstract class BinderTransport
|
|||
|
||||
@GuardedBy("this")
|
||||
private int latestCallId = FIRST_CALL_ID;
|
||||
|
||||
@GuardedBy("this")
|
||||
private ScheduledFuture<?> readyTimeoutFuture; // != null iff timeout scheduled.
|
||||
|
||||
|
|
@ -592,8 +591,11 @@ public abstract class BinderTransport
|
|||
ClientTransportOptions options) {
|
||||
super(
|
||||
factory.scheduledExecutorPool,
|
||||
buildClientAttributes(options.getEagAttributes(),
|
||||
factory.sourceContext, targetAddress, factory.inboundParcelablePolicy),
|
||||
buildClientAttributes(
|
||||
options.getEagAttributes(),
|
||||
factory.sourceContext,
|
||||
targetAddress,
|
||||
factory.inboundParcelablePolicy),
|
||||
factory.binderDecorator,
|
||||
buildLogId(factory.sourceContext, targetAddress));
|
||||
this.offloadExecutorPool = factory.offloadExecutorPool;
|
||||
|
|
@ -622,7 +624,8 @@ public abstract class BinderTransport
|
|||
|
||||
@Override
|
||||
public synchronized void onBound(IBinder binder) {
|
||||
sendSetupTransaction(binderDecorator.decorate(OneWayBinderProxy.wrap(binder, offloadExecutor)));
|
||||
sendSetupTransaction(
|
||||
binderDecorator.decorate(OneWayBinderProxy.wrap(binder, offloadExecutor)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -640,8 +643,12 @@ public abstract class BinderTransport
|
|||
setState(TransportState.SETUP);
|
||||
serviceBinding.bind();
|
||||
if (readyTimeoutMillis >= 0) {
|
||||
readyTimeoutFuture = getScheduledExecutorService().schedule(
|
||||
BinderClientTransport.this::onReadyTimeout, readyTimeoutMillis, MILLISECONDS);
|
||||
readyTimeoutFuture =
|
||||
getScheduledExecutorService()
|
||||
.schedule(
|
||||
BinderClientTransport.this::onReadyTimeout,
|
||||
readyTimeoutMillis,
|
||||
MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -651,8 +658,9 @@ public abstract class BinderTransport
|
|||
private synchronized void onReadyTimeout() {
|
||||
if (inState(TransportState.SETUP)) {
|
||||
readyTimeoutFuture = null;
|
||||
shutdownInternal(Status.DEADLINE_EXCEEDED
|
||||
.withDescription("Connect timeout " + readyTimeoutMillis + "ms lapsed"),
|
||||
shutdownInternal(
|
||||
Status.DEADLINE_EXCEEDED.withDescription(
|
||||
"Connect timeout " + readyTimeoutMillis + "ms lapsed"),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
|
@ -760,17 +768,23 @@ public abstract class BinderTransport
|
|||
shutdownInternal(
|
||||
Status.UNAVAILABLE.withDescription("Malformed SETUP_TRANSPORT data"), true);
|
||||
} else {
|
||||
ListenableFuture<Status> authFuture = (securityPolicy instanceof AsyncSecurityPolicy) ?
|
||||
((AsyncSecurityPolicy) securityPolicy).checkAuthorizationAsync(remoteUid) :
|
||||
Futures.submit(() -> securityPolicy.checkAuthorization(remoteUid), offloadExecutor);
|
||||
ListenableFuture<Status> authFuture =
|
||||
(securityPolicy instanceof AsyncSecurityPolicy)
|
||||
? ((AsyncSecurityPolicy) securityPolicy).checkAuthorizationAsync(remoteUid)
|
||||
: Futures.submit(
|
||||
() -> securityPolicy.checkAuthorization(remoteUid), offloadExecutor);
|
||||
Futures.addCallback(
|
||||
authFuture,
|
||||
new FutureCallback<Status>() {
|
||||
@Override
|
||||
public void onSuccess(Status result) { handleAuthResult(binder, result); }
|
||||
public void onSuccess(Status result) {
|
||||
handleAuthResult(binder, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) { handleAuthResult(t); }
|
||||
public void onFailure(Throwable t) {
|
||||
handleAuthResult(t);
|
||||
}
|
||||
},
|
||||
offloadExecutor);
|
||||
}
|
||||
|
|
@ -802,10 +816,7 @@ public abstract class BinderTransport
|
|||
|
||||
private synchronized void handleAuthResult(Throwable t) {
|
||||
shutdownInternal(
|
||||
Status.INTERNAL
|
||||
.withDescription("Could not evaluate SecurityPolicy")
|
||||
.withCause(t),
|
||||
true);
|
||||
Status.INTERNAL.withDescription("Could not evaluate SecurityPolicy").withCause(t), true);
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
|
|
@ -815,8 +826,7 @@ public abstract class BinderTransport
|
|||
}
|
||||
|
||||
private static ClientStream newFailingClientStream(
|
||||
Status failure, Attributes attributes, Metadata headers,
|
||||
ClientStreamTracer[] tracers) {
|
||||
Status failure, Attributes attributes, Metadata headers, ClientStreamTracer[] tracers) {
|
||||
StatsTraceContext statsTraceContext =
|
||||
StatsTraceContext.newClientContext(tracers, attributes, headers);
|
||||
statsTraceContext.clientOutboundHeaders();
|
||||
|
|
@ -858,7 +868,8 @@ public abstract class BinderTransport
|
|||
|
||||
/** Concrete server-side transport implementation. */
|
||||
@Internal
|
||||
public static final class BinderServerTransport extends BinderTransport implements ServerTransport {
|
||||
public static final class BinderServerTransport extends BinderTransport
|
||||
implements ServerTransport {
|
||||
|
||||
private final List<ServerStreamTracer.Factory> streamTracerFactories;
|
||||
@Nullable private ServerTransportListener serverTransportListener;
|
||||
|
|
@ -880,7 +891,8 @@ public abstract class BinderTransport
|
|||
setOutgoingBinder(OneWayBinderProxy.wrap(callbackBinder, getScheduledExecutorService()));
|
||||
}
|
||||
|
||||
public synchronized void setServerTransportListener(ServerTransportListener serverTransportListener) {
|
||||
public synchronized void setServerTransportListener(
|
||||
ServerTransportListener serverTransportListener) {
|
||||
this.serverTransportListener = serverTransportListener;
|
||||
if (isShutdown()) {
|
||||
setState(TransportState.SHUTDOWN_TERMINATED);
|
||||
|
|
@ -983,4 +995,3 @@ public abstract class BinderTransport
|
|||
return Status.INTERNAL.withCause(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ import javax.annotation.Nullable;
|
|||
/**
|
||||
* Manages security for an Android Service hosted gRPC server.
|
||||
*
|
||||
* <p>Attaches authorization state to a newly-created transport, and contains a
|
||||
* ServerInterceptor which ensures calls are authorized before allowing them to proceed.
|
||||
* <p>Attaches authorization state to a newly-created transport, and contains a ServerInterceptor
|
||||
* which ensures calls are authorized before allowing them to proceed.
|
||||
*/
|
||||
public final class BinderTransportSecurity {
|
||||
|
||||
|
|
@ -205,15 +205,18 @@ public final class BinderTransportSecurity {
|
|||
serverPolicyChecker.checkAuthorizationForServiceAsync(uid, serviceName);
|
||||
if (useCache) {
|
||||
serviceAuthorization.putIfAbsent(serviceName, authorization);
|
||||
Futures.addCallback(authorization, new FutureCallback<Status>() {
|
||||
@Override
|
||||
public void onSuccess(Status result) {}
|
||||
Futures.addCallback(
|
||||
authorization,
|
||||
new FutureCallback<Status>() {
|
||||
@Override
|
||||
public void onSuccess(Status result) {}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
serviceAuthorization.remove(serviceName, authorization);
|
||||
}
|
||||
}, MoreExecutors.directExecutor());
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
serviceAuthorization.remove(serviceName, authorization);
|
||||
}
|
||||
},
|
||||
MoreExecutors.directExecutor());
|
||||
}
|
||||
return authorization;
|
||||
}
|
||||
|
|
@ -238,7 +241,7 @@ public final class BinderTransportSecurity {
|
|||
* @param uid The Android UID to authenticate.
|
||||
* @param serviceName The name of the gRPC service being called.
|
||||
* @return a future with the result of the authorization check. A failed future represents a
|
||||
* failure to perform the authorization check, not that the access is denied.
|
||||
* failure to perform the authorization check, not that the access is denied.
|
||||
*/
|
||||
ListenableFuture<Status> checkAuthorizationForServiceAsync(int uid, String serviceName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,20 +28,17 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||
/**
|
||||
* A simple InputStream from a 2-dimensional byte array.
|
||||
*
|
||||
* Used to provide message data from incoming blocks of data. It is assumed that
|
||||
* all byte arrays passed in the constructor of this this class are owned by the new
|
||||
* instance.
|
||||
* <p>Used to provide message data from incoming blocks of data. It is assumed that all byte arrays
|
||||
* passed in the constructor of this this class are owned by the new instance.
|
||||
*
|
||||
* This also assumes byte arrays are created by the BlockPool class, and should
|
||||
* be returned to it when this class is closed.
|
||||
* <p>This also assumes byte arrays are created by the BlockPool class, and should be returned to it
|
||||
* when this class is closed.
|
||||
*/
|
||||
@NotThreadSafe
|
||||
final class BlockInputStream extends InputStream implements KnownLength, Drainable {
|
||||
|
||||
@Nullable
|
||||
private byte[][] blocks;
|
||||
@Nullable
|
||||
private byte[] currentBlock;
|
||||
@Nullable private byte[][] blocks;
|
||||
@Nullable private byte[] currentBlock;
|
||||
private int blockIndex;
|
||||
private int blockOffset;
|
||||
private int available;
|
||||
|
|
@ -50,8 +47,7 @@ final class BlockInputStream extends InputStream implements KnownLength, Drainab
|
|||
/**
|
||||
* Creates a new stream with a single block.
|
||||
*
|
||||
* @param block The single byte array block, ownership of which is
|
||||
* passed to this instance.
|
||||
* @param block The single byte array block, ownership of which is passed to this instance.
|
||||
*/
|
||||
BlockInputStream(byte[] block) {
|
||||
this.blocks = null;
|
||||
|
|
@ -62,10 +58,10 @@ final class BlockInputStream extends InputStream implements KnownLength, Drainab
|
|||
/**
|
||||
* Creates a new stream from a sequence of blocks.
|
||||
*
|
||||
* @param blocks A two dimensional byte array containing the data. Ownership
|
||||
* of all blocks is passed to this instance.
|
||||
* @param available The number of bytes available in total. This may be
|
||||
* less than (but never more than) the total size of all byte arrays in blocks.
|
||||
* @param blocks A two dimensional byte array containing the data. Ownership of all blocks is
|
||||
* passed to this instance.
|
||||
* @param available The number of bytes available in total. This may be less than (but never more
|
||||
* than) the total size of all byte arrays in blocks.
|
||||
*/
|
||||
BlockInputStream(byte[][] blocks, int available) {
|
||||
this.blocks = blocks;
|
||||
|
|
|
|||
|
|
@ -27,9 +27,8 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||
* byte array of size N. This means we can't simply read into a large block and be done with it, we
|
||||
* need to allocate a new buffer specifically. Boo, Android.
|
||||
*
|
||||
* <p>When writing data though, we can use a fixed-size buffer, so when large messages are
|
||||
* split into standard-sized blocks, we only need a byte array allocation to read the last
|
||||
* block.
|
||||
* <p>When writing data though, we can use a fixed-size buffer, so when large messages are split
|
||||
* into standard-sized blocks, we only need a byte array allocation to read the last block.
|
||||
*
|
||||
* <p>This class maintains a pool of blocks of standard size, but also provides smaller blocks when
|
||||
* requested. Currently, blocks of standard size are retained in the pool, when released, but we
|
||||
|
|
@ -38,8 +37,8 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||
final class BlockPool {
|
||||
|
||||
/**
|
||||
* The size of each standard block. (Currently 16k)
|
||||
* The block size must be at least as large as the maximum header list size.
|
||||
* The size of each standard block. (Currently 16k) The block size must be at least as large as
|
||||
* the maximum header list size.
|
||||
*/
|
||||
private static final int BLOCK_SIZE = Math.max(16 * 1024, GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE);
|
||||
|
||||
|
|
|
|||
|
|
@ -344,8 +344,7 @@ abstract class Inbound<L extends StreamListener> implements StreamListener.Messa
|
|||
}
|
||||
int index = parcel.readInt();
|
||||
boolean hasPrefix = TransactionUtils.hasFlag(flags, TransactionUtils.FLAG_PREFIX);
|
||||
boolean hasMessageData =
|
||||
TransactionUtils.hasFlag(flags, TransactionUtils.FLAG_MESSAGE_DATA);
|
||||
boolean hasMessageData = TransactionUtils.hasFlag(flags, TransactionUtils.FLAG_MESSAGE_DATA);
|
||||
boolean hasSuffix = TransactionUtils.hasFlag(flags, TransactionUtils.FLAG_SUFFIX);
|
||||
if (hasPrefix) {
|
||||
handlePrefix(flags, parcel);
|
||||
|
|
|
|||
|
|
@ -71,9 +71,7 @@ public final class LeakSafeOneWayBinder extends Binder {
|
|||
setHandler(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the current {@link TransactionHandler} with `handler`.
|
||||
*/
|
||||
/** Replaces the current {@link TransactionHandler} with `handler`. */
|
||||
public void setHandler(@Nullable TransactionHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public final class MetadataHelper {
|
|||
|
||||
/** The generic metadata marshaller we use for reading parcelables from the transport. */
|
||||
private static final Metadata.BinaryStreamMarshaller<Parcelable> TRANSPORT_INBOUND_MARSHALLER =
|
||||
new ParcelableMetadataMarshaller<>(null, true);
|
||||
new ParcelableMetadataMarshaller<>(null, true);
|
||||
|
||||
/** Indicates the following value is a parcelable. */
|
||||
private static final int PARCELABLE_SENTINEL = -1;
|
||||
|
|
@ -96,14 +96,16 @@ public final class MetadataHelper {
|
|||
InputStream stream = (InputStream) value;
|
||||
int total = 0;
|
||||
while (total < buffer.length) {
|
||||
int read = stream.read(buffer, total, buffer.length - total);
|
||||
int read = stream.read(buffer, total, buffer.length - total);
|
||||
if (read == -1) {
|
||||
break;
|
||||
}
|
||||
total += read;
|
||||
}
|
||||
if (total == buffer.length) {
|
||||
throw Status.RESOURCE_EXHAUSTED.withDescription("Metadata value too large").asException();
|
||||
throw Status.RESOURCE_EXHAUSTED
|
||||
.withDescription("Metadata value too large")
|
||||
.asException();
|
||||
}
|
||||
parcel.writeInt(total);
|
||||
if (total > 0) {
|
||||
|
|
@ -182,10 +184,8 @@ public final class MetadataHelper {
|
|||
}
|
||||
|
||||
/** Read a byte array checking that we're not reading too much. */
|
||||
private static byte[] readBytesChecked(
|
||||
Parcel parcel,
|
||||
int numBytes,
|
||||
int bytesRead) throws StatusException {
|
||||
private static byte[] readBytesChecked(Parcel parcel, int numBytes, int bytesRead)
|
||||
throws StatusException {
|
||||
if (bytesRead + numBytes > GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE) {
|
||||
throw Status.RESOURCE_EXHAUSTED.withDescription("Metadata too large").asException();
|
||||
}
|
||||
|
|
@ -203,7 +203,8 @@ public final class MetadataHelper {
|
|||
@Nullable private final Parcelable.Creator<P> creator;
|
||||
private final boolean immutableType;
|
||||
|
||||
public ParcelableMetadataMarshaller(@Nullable Parcelable.Creator<P> creator, boolean immutableType) {
|
||||
public ParcelableMetadataMarshaller(
|
||||
@Nullable Parcelable.Creator<P> creator, boolean immutableType) {
|
||||
this.creator = creator;
|
||||
this.immutableType = immutableType;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,15 +71,13 @@ public abstract class OneWayBinderProxy {
|
|||
*/
|
||||
public interface Decorator {
|
||||
/**
|
||||
* Returns an instance of {@link OneWayBinderProxy} that decorates {@code input} with some
|
||||
* new behavior.
|
||||
* Returns an instance of {@link OneWayBinderProxy} that decorates {@code input} with some new
|
||||
* behavior.
|
||||
*/
|
||||
OneWayBinderProxy decorate(OneWayBinderProxy input);
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link Decorator} that does nothing.
|
||||
*/
|
||||
/** A {@link Decorator} that does nothing. */
|
||||
public static final Decorator IDENTITY_DECORATOR = (x) -> x;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -4,10 +4,8 @@ import io.grpc.Metadata;
|
|||
import io.grpc.ServerCall;
|
||||
import io.grpc.ServerCallHandler;
|
||||
import io.grpc.Status;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
|
|
@ -23,16 +21,14 @@ final class PendingAuthListener<ReqT, RespT> extends ServerCall.Listener<ReqT> {
|
|||
|
||||
PendingAuthListener() {}
|
||||
|
||||
void startCall(ServerCall<ReqT, RespT> call,
|
||||
Metadata headers,
|
||||
ServerCallHandler<ReqT, RespT> next) {
|
||||
void startCall(
|
||||
ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) {
|
||||
ServerCall.Listener<ReqT> delegate;
|
||||
try {
|
||||
delegate = next.startCall(call, headers);
|
||||
} catch (RuntimeException e) {
|
||||
call.close(
|
||||
Status
|
||||
.INTERNAL
|
||||
Status.INTERNAL
|
||||
.withCause(e)
|
||||
.withDescription("Failed to start server call after authorization check"),
|
||||
new Metadata());
|
||||
|
|
|
|||
|
|
@ -106,8 +106,7 @@ final class PingTracker {
|
|||
private synchronized void success() {
|
||||
if (!done) {
|
||||
done = true;
|
||||
executor.execute(
|
||||
() -> callback.onSuccess(ticker.read() - startTimeNanos));
|
||||
executor.execute(() -> callback.onSuccess(ticker.read() - startTimeNanos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,12 +147,7 @@ final class ServiceBinding implements Bindable, ServiceConnection {
|
|||
state = State.BINDING;
|
||||
Status bindResult =
|
||||
bindInternal(
|
||||
sourceContext,
|
||||
bindIntent,
|
||||
this,
|
||||
bindFlags,
|
||||
channelCredentials,
|
||||
targetUserHandle);
|
||||
sourceContext, bindIntent, this, bindFlags, channelCredentials, targetUserHandle);
|
||||
if (!bindResult.isOk()) {
|
||||
handleBindServiceFailure(sourceContext, this);
|
||||
state = State.UNBOUND;
|
||||
|
|
@ -184,7 +179,7 @@ final class ServiceBinding implements Bindable, ServiceConnection {
|
|||
}
|
||||
boolean bindResult = false;
|
||||
switch (bindMethodType) {
|
||||
case BIND_SERVICE:
|
||||
case BIND_SERVICE:
|
||||
bindResult = context.bindService(bindIntent, conn, flags);
|
||||
break;
|
||||
case BIND_SERVICE_AS_USER:
|
||||
|
|
@ -193,17 +188,18 @@ final class ServiceBinding implements Bindable, ServiceConnection {
|
|||
case DEVICE_POLICY_BIND_SEVICE_ADMIN:
|
||||
DevicePolicyManager devicePolicyManager =
|
||||
(DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
bindResult = devicePolicyManager.bindDeviceAdminServiceAsUser(
|
||||
channelCredentials.getDevicePolicyAdminComponentName(),
|
||||
bindIntent,
|
||||
conn,
|
||||
flags,
|
||||
targetUserHandle);
|
||||
bindResult =
|
||||
devicePolicyManager.bindDeviceAdminServiceAsUser(
|
||||
channelCredentials.getDevicePolicyAdminComponentName(),
|
||||
bindIntent,
|
||||
conn,
|
||||
flags,
|
||||
targetUserHandle);
|
||||
break;
|
||||
}
|
||||
if (!bindResult) {
|
||||
return Status.UNIMPLEMENTED.withDescription(
|
||||
bindMethodType.methodName() + "(" + bindIntent + ") returned false");
|
||||
bindMethodType.methodName() + "(" + bindIntent + ") returned false");
|
||||
}
|
||||
return Status.OK;
|
||||
} catch (SecurityException e) {
|
||||
|
|
@ -211,8 +207,9 @@ final class ServiceBinding implements Bindable, ServiceConnection {
|
|||
.withCause(e)
|
||||
.withDescription("SecurityException from " + bindMethodType.methodName());
|
||||
} catch (RuntimeException e) {
|
||||
return Status.INTERNAL.withCause(e).withDescription(
|
||||
"RuntimeException from " + bindMethodType.methodName());
|
||||
return Status.INTERNAL
|
||||
.withCause(e)
|
||||
.withDescription("RuntimeException from " + bindMethodType.methodName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,10 +25,13 @@ import javax.annotation.Nullable;
|
|||
final class TransactionUtils {
|
||||
/** Set when the transaction contains rpc prefix data. */
|
||||
static final int FLAG_PREFIX = 0x1;
|
||||
|
||||
/** Set when the transaction contains some message data. */
|
||||
static final int FLAG_MESSAGE_DATA = 0x2;
|
||||
|
||||
/** Set when the transaction contains rpc suffix data. */
|
||||
static final int FLAG_SUFFIX = 0x4;
|
||||
|
||||
/** Set when the transaction is an out-of-band close event. */
|
||||
static final int FLAG_OUT_OF_BAND_CLOSE = 0x8;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public class BinderChannelCredentialsTest {
|
|||
BinderChannelCredentials channelCredentials = BinderChannelCredentials.forDefault();
|
||||
assertThat(channelCredentials.getDevicePolicyAdminComponentName()).isNull();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void binderChannelCredentialsForDevicePolicyAdmin() {
|
||||
String deviceAdminClassName = "DevicePolicyAdmin";
|
||||
|
|
|
|||
|
|
@ -31,4 +31,4 @@ public class PeerUidTest {
|
|||
.addEqualityGroup(new PeerUid(456))
|
||||
.testEquals();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public final class PeerUidTestHelperTest {
|
||||
|
||||
@Rule
|
||||
public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
|
||||
@Rule public final GrpcCleanupRule grpcCleanup = new GrpcCleanupRule();
|
||||
|
||||
private static final int FAKE_UID = 12345;
|
||||
|
||||
|
|
|
|||
|
|
@ -133,4 +133,4 @@ public class PeerUidsTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,9 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import io.grpc.binder.internal.MainThreadScheduledExecutorService;
|
||||
import android.app.Application;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import androidx.lifecycle.LifecycleService;
|
||||
|
|
@ -44,6 +42,7 @@ import io.grpc.ServerMethodDefinition;
|
|||
import io.grpc.ServerServiceDefinition;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.grpc.binder.internal.MainThreadScheduledExecutorService;
|
||||
import io.grpc.protobuf.lite.ProtoLiteUtils;
|
||||
import io.grpc.stub.ClientCalls;
|
||||
import io.grpc.stub.ServerCalls;
|
||||
|
|
@ -249,8 +248,5 @@ public final class RobolectricBinderSecurityTest {
|
|||
}
|
||||
|
||||
/** A future representing a task submitted to a {@link Handler}. */
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,8 +107,7 @@ public final class SecurityPoliciesTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testHasSignature_succeedsIfPackageNameAndSignaturesMatch()
|
||||
throws Exception {
|
||||
public void testHasSignature_succeedsIfPackageNameAndSignaturesMatch() throws Exception {
|
||||
PackageInfo info =
|
||||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
|
||||
|
|
@ -152,8 +151,7 @@ public final class SecurityPoliciesTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testOneOfSignatures_succeedsIfPackageNameAndSignaturesMatch()
|
||||
throws Exception {
|
||||
public void testOneOfSignatures_succeedsIfPackageNameAndSignaturesMatch() throws Exception {
|
||||
PackageInfo info =
|
||||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
|
||||
|
|
@ -189,8 +187,7 @@ public final class SecurityPoliciesTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testOneOfSignature_succeedsIfPackageNameAndOneOfSignaturesMatch()
|
||||
throws Exception {
|
||||
public void testOneOfSignature_succeedsIfPackageNameAndOneOfSignaturesMatch() throws Exception {
|
||||
PackageInfo info =
|
||||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
|
||||
|
|
@ -206,11 +203,7 @@ public final class SecurityPoliciesTest {
|
|||
|
||||
@Test
|
||||
public void testHasSignature_failsIfUidUnknown() throws Exception {
|
||||
policy =
|
||||
SecurityPolicies.hasSignature(
|
||||
packageManager,
|
||||
appContext.getPackageName(),
|
||||
SIG1);
|
||||
policy = SecurityPolicies.hasSignature(packageManager, appContext.getPackageName(), SIG1);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID_UNKNOWN).getCode())
|
||||
.isEqualTo(Status.UNAUTHENTICATED.getCode());
|
||||
|
|
@ -335,8 +328,7 @@ public final class SecurityPoliciesTest {
|
|||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
|
||||
installPackages(OTHER_UID, info);
|
||||
shadowOf(devicePolicyManager)
|
||||
.setDeviceOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
shadowOf(devicePolicyManager).setDeviceOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
|
||||
policy = SecurityPolicies.isDeviceOwner(appContext);
|
||||
|
||||
|
|
@ -352,17 +344,18 @@ public final class SecurityPoliciesTest {
|
|||
|
||||
policy = SecurityPolicies.isDeviceOwner(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsDeviceOwner_failsWhenNoPackagesForUid() throws Exception {
|
||||
policy = SecurityPolicies.isDeviceOwner(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.UNAUTHENTICATED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.UNAUTHENTICATED.getCode());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Config(sdk = 21)
|
||||
public void testIsProfileOwner_succeedsForProfileOwner() throws Exception {
|
||||
|
|
@ -370,8 +363,7 @@ public final class SecurityPoliciesTest {
|
|||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
|
||||
installPackages(OTHER_UID, info);
|
||||
shadowOf(devicePolicyManager)
|
||||
.setProfileOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
shadowOf(devicePolicyManager).setProfileOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
|
||||
policy = SecurityPolicies.isProfileOwner(appContext);
|
||||
|
||||
|
|
@ -388,7 +380,8 @@ public final class SecurityPoliciesTest {
|
|||
|
||||
policy = SecurityPolicies.isProfileOwner(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -396,7 +389,8 @@ public final class SecurityPoliciesTest {
|
|||
public void testIsProfileOwner_failsWhenNoPackagesForUid() throws Exception {
|
||||
policy = SecurityPolicies.isProfileOwner(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.UNAUTHENTICATED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.UNAUTHENTICATED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -406,14 +400,12 @@ public final class SecurityPoliciesTest {
|
|||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
|
||||
installPackages(OTHER_UID, info);
|
||||
shadowOf(devicePolicyManager)
|
||||
.setProfileOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
shadowOf(devicePolicyManager).setProfileOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
shadowOf(devicePolicyManager).setOrganizationOwnedDeviceWithManagedProfile(true);
|
||||
|
||||
policy = SecurityPolicies.isProfileOwnerOnOrganizationOwnedDevice(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.OK.getCode());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -423,13 +415,13 @@ public final class SecurityPoliciesTest {
|
|||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
|
||||
installPackages(OTHER_UID, info);
|
||||
shadowOf(devicePolicyManager)
|
||||
.setProfileOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
shadowOf(devicePolicyManager).setProfileOwner(new ComponentName(OTHER_UID_PACKAGE_NAME, "foo"));
|
||||
shadowOf(devicePolicyManager).setOrganizationOwnedDeviceWithManagedProfile(false);
|
||||
|
||||
policy = SecurityPolicies.isProfileOwnerOnOrganizationOwnedDevice(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -442,7 +434,8 @@ public final class SecurityPoliciesTest {
|
|||
|
||||
policy = SecurityPolicies.isProfileOwnerOnOrganizationOwnedDevice(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -450,7 +443,8 @@ public final class SecurityPoliciesTest {
|
|||
public void testIsProfileOwnerOnOrgOwned_failsWhenNoPackagesForUid() throws Exception {
|
||||
policy = SecurityPolicies.isProfileOwnerOnOrganizationOwnedDevice(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.UNAUTHENTICATED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.UNAUTHENTICATED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -463,7 +457,8 @@ public final class SecurityPoliciesTest {
|
|||
|
||||
policy = SecurityPolicies.isProfileOwner(appContext);
|
||||
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode()).isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
assertThat(policy.checkAuthorization(OTHER_UID).getCode())
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
}
|
||||
|
||||
private static PackageInfoBuilder newBuilder() {
|
||||
|
|
@ -490,7 +485,7 @@ public final class SecurityPoliciesTest {
|
|||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // 'signatures': We don't yet support signing cert rotation.
|
||||
@SuppressWarnings("deprecation") // 'signatures': We don't yet support signing cert rotation.
|
||||
public PackageInfo build() {
|
||||
checkState(this.packageName != null, "packageName is a mandatory field");
|
||||
|
||||
|
|
@ -667,8 +662,8 @@ public final class SecurityPoliciesTest {
|
|||
|
||||
@Test
|
||||
public void
|
||||
testOneOfSignatureSha256Hash_failsIfPackageNameDoNotMatchAndOneOfSignatureHashesMatch()
|
||||
throws Exception {
|
||||
testOneOfSignatureSha256Hash_failsIfPackageNameDoNotMatchAndOneOfSignatureHashesMatch()
|
||||
throws Exception {
|
||||
PackageInfo info =
|
||||
newBuilder().setPackageName(OTHER_UID_PACKAGE_NAME).setSignatures(SIG2).build();
|
||||
installPackages(OTHER_UID, info);
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ package io.grpc.binder;
|
|||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.os.Process;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
|
@ -27,18 +27,16 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.google.common.util.concurrent.Uninterruptibles;
|
||||
|
||||
import io.grpc.Status;
|
||||
import io.grpc.Status.Code;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import java.util.concurrent.BrokenBarrierException;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.CyclicBarrier;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class ServerSecurityPolicyTest {
|
||||
|
|
@ -126,7 +124,6 @@ public final class ServerSecurityPolicyTest {
|
|||
.isEqualTo(Status.OK.getCode());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
public void testPerService_legacyApi() {
|
||||
|
|
@ -149,13 +146,16 @@ public final class ServerSecurityPolicyTest {
|
|||
public void testPerServiceAsync() throws Exception {
|
||||
policy =
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy(SERVICE2, asyncPolicy(uid -> {
|
||||
// Add some extra future transformation to confirm that a chain
|
||||
// of futures gets properly handled.
|
||||
ListenableFuture<Void> dependency = Futures.immediateVoidFuture();
|
||||
return Futures
|
||||
.transform(dependency, unused -> Status.OK, MoreExecutors.directExecutor());
|
||||
}))
|
||||
.servicePolicy(
|
||||
SERVICE2,
|
||||
asyncPolicy(
|
||||
uid -> {
|
||||
// Add some extra future transformation to confirm that a chain
|
||||
// of futures gets properly handled.
|
||||
ListenableFuture<Void> dependency = Futures.immediateVoidFuture();
|
||||
return Futures.transform(
|
||||
dependency, unused -> Status.OK, MoreExecutors.directExecutor());
|
||||
}))
|
||||
.build();
|
||||
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, MY_UID, SERVICE1))
|
||||
|
|
@ -172,11 +172,12 @@ public final class ServerSecurityPolicyTest {
|
|||
public void testPerService_failedSecurityPolicyFuture_returnsAFailedFuture() {
|
||||
policy =
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy(SERVICE1, asyncPolicy(uid ->
|
||||
Futures
|
||||
.immediateFailedFuture(
|
||||
new IllegalStateException("something went wrong"))
|
||||
))
|
||||
.servicePolicy(
|
||||
SERVICE1,
|
||||
asyncPolicy(
|
||||
uid ->
|
||||
Futures.immediateFailedFuture(
|
||||
new IllegalStateException("something went wrong"))))
|
||||
.build();
|
||||
|
||||
ListenableFuture<Status> statusFuture =
|
||||
|
|
@ -203,24 +204,31 @@ public final class ServerSecurityPolicyTest {
|
|||
ListeningExecutorService listeningExecutorService =
|
||||
MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
|
||||
CountDownLatch unsatisfiedLatch = new CountDownLatch(1);
|
||||
ListenableFuture<Status> toBeInterruptedFuture = listeningExecutorService.submit(() -> {
|
||||
unsatisfiedLatch.await(); // waits forever
|
||||
return null;
|
||||
});
|
||||
ListenableFuture<Status> toBeInterruptedFuture =
|
||||
listeningExecutorService.submit(
|
||||
() -> {
|
||||
unsatisfiedLatch.await(); // waits forever
|
||||
return null;
|
||||
});
|
||||
|
||||
CyclicBarrier barrier = new CyclicBarrier(2);
|
||||
Thread testThread = Thread.currentThread();
|
||||
new Thread(() -> {
|
||||
awaitOrFail(barrier);
|
||||
testThread.interrupt();
|
||||
}).start();
|
||||
new Thread(
|
||||
() -> {
|
||||
awaitOrFail(barrier);
|
||||
testThread.interrupt();
|
||||
})
|
||||
.start();
|
||||
|
||||
policy =
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy(SERVICE1, asyncPolicy(unused -> {
|
||||
awaitOrFail(barrier);
|
||||
return toBeInterruptedFuture;
|
||||
}))
|
||||
.servicePolicy(
|
||||
SERVICE1,
|
||||
asyncPolicy(
|
||||
unused -> {
|
||||
awaitOrFail(barrier);
|
||||
return toBeInterruptedFuture;
|
||||
}))
|
||||
.build();
|
||||
ListenableFuture<Status> statusFuture =
|
||||
policy.checkAuthorizationForServiceAsync(MY_UID, SERVICE1);
|
||||
|
|
@ -247,13 +255,16 @@ public final class ServerSecurityPolicyTest {
|
|||
// Uses the specified policy for service2.
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, MY_UID, SERVICE2))
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, OTHER_UID, SERVICE2)).isEqualTo(Status.OK.getCode());
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, OTHER_UID, SERVICE2))
|
||||
.isEqualTo(Status.OK.getCode());
|
||||
|
||||
// Falls back to the default.
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, MY_UID, SERVICE3)).isEqualTo(Status.OK.getCode());
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, MY_UID, SERVICE3))
|
||||
.isEqualTo(Status.OK.getCode());
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, OTHER_UID, SERVICE3))
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Deprecated
|
||||
public void testPerServiceNoDefault_legacyApi() {
|
||||
|
|
@ -286,44 +297,40 @@ public final class ServerSecurityPolicyTest {
|
|||
@Test
|
||||
public void testPerServiceNoDefaultAsync() throws Exception {
|
||||
policy =
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy(
|
||||
SERVICE1,
|
||||
asyncPolicy((uid) -> Futures.immediateFuture(Status.INTERNAL)))
|
||||
.servicePolicy(
|
||||
SERVICE2, asyncPolicy((uid) -> {
|
||||
// Add some extra future transformation to confirm that a chain
|
||||
// of futures gets properly handled.
|
||||
ListenableFuture<Boolean> anotherUidFuture =
|
||||
Futures.immediateFuture(uid == OTHER_UID);
|
||||
return Futures
|
||||
.transform(
|
||||
anotherUidFuture,
|
||||
anotherUid ->
|
||||
anotherUid
|
||||
? Status.OK
|
||||
: Status.PERMISSION_DENIED,
|
||||
MoreExecutors.directExecutor());
|
||||
}))
|
||||
.build();
|
||||
ServerSecurityPolicy.newBuilder()
|
||||
.servicePolicy(SERVICE1, asyncPolicy((uid) -> Futures.immediateFuture(Status.INTERNAL)))
|
||||
.servicePolicy(
|
||||
SERVICE2,
|
||||
asyncPolicy(
|
||||
(uid) -> {
|
||||
// Add some extra future transformation to confirm that a chain
|
||||
// of futures gets properly handled.
|
||||
ListenableFuture<Boolean> anotherUidFuture =
|
||||
Futures.immediateFuture(uid == OTHER_UID);
|
||||
return Futures.transform(
|
||||
anotherUidFuture,
|
||||
anotherUid -> anotherUid ? Status.OK : Status.PERMISSION_DENIED,
|
||||
MoreExecutors.directExecutor());
|
||||
}))
|
||||
.build();
|
||||
|
||||
// Uses the specified policy for service1.
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, MY_UID, SERVICE1))
|
||||
.isEqualTo(Status.INTERNAL.getCode());
|
||||
.isEqualTo(Status.INTERNAL.getCode());
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, OTHER_UID, SERVICE1))
|
||||
.isEqualTo(Status.INTERNAL.getCode());
|
||||
.isEqualTo(Status.INTERNAL.getCode());
|
||||
|
||||
// Uses the specified policy for service2.
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, MY_UID, SERVICE2))
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, OTHER_UID, SERVICE2))
|
||||
.isEqualTo(Status.OK.getCode());
|
||||
.isEqualTo(Status.OK.getCode());
|
||||
|
||||
// Falls back to the default.
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, MY_UID, SERVICE3))
|
||||
.isEqualTo(Status.OK.getCode());
|
||||
.isEqualTo(Status.OK.getCode());
|
||||
assertThat(checkAuthorizationForServiceAsync(policy, OTHER_UID, SERVICE3))
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
.isEqualTo(Status.PERMISSION_DENIED.getCode());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -331,9 +338,7 @@ public final class ServerSecurityPolicyTest {
|
|||
* dealing with concurrency details. Returns a {link @Status.Code} for convenience.
|
||||
*/
|
||||
private static Status.Code checkAuthorizationForServiceAsync(
|
||||
ServerSecurityPolicy policy,
|
||||
int callerUid,
|
||||
String service) throws ExecutionException {
|
||||
ServerSecurityPolicy policy, int callerUid, String service) throws ExecutionException {
|
||||
ListenableFuture<Status> statusFuture =
|
||||
policy.checkAuthorizationForServiceAsync(callerUid, service);
|
||||
return Uninterruptibles.getUninterruptibly(statusFuture).getCode();
|
||||
|
|
@ -359,12 +364,12 @@ public final class ServerSecurityPolicyTest {
|
|||
|
||||
private static void awaitOrFail(CyclicBarrier barrier) {
|
||||
try {
|
||||
barrier.await();
|
||||
barrier.await();
|
||||
} catch (BrokenBarrierException e) {
|
||||
fail(e.getMessage());
|
||||
fail(e.getMessage());
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
fail(e.getMessage());
|
||||
Thread.currentThread().interrupt();
|
||||
fail(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import com.google.common.collect.ImmutableList;
|
|||
import io.grpc.Attributes;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.binder.internal.MainThreadScheduledExecutorService;
|
||||
import io.grpc.internal.FixedObjectPool;
|
||||
import io.grpc.internal.ServerStream;
|
||||
import io.grpc.internal.ServerTransportListener;
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ public final class BlockInputStreamTest {
|
|||
|
||||
@Test
|
||||
public void testSingleBlock() throws Exception {
|
||||
BlockInputStream bis =
|
||||
new BlockInputStream(new byte[][] {getBytes(10, 1)}, 10);
|
||||
BlockInputStream bis = new BlockInputStream(new byte[][] {getBytes(10, 1)}, 10);
|
||||
assertThat(bis.read(buff, 0, 20)).isEqualTo(10);
|
||||
assertBytes(buff, 0, 10, 1);
|
||||
}
|
||||
|
|
@ -95,8 +94,7 @@ public final class BlockInputStreamTest {
|
|||
|
||||
@Test
|
||||
public void testMultipleBlocksEmptyFinalBlock() throws Exception {
|
||||
BlockInputStream bis =
|
||||
new BlockInputStream(new byte[][] {getBytes(10, 1), getBytes(0, 0)}, 10);
|
||||
BlockInputStream bis = new BlockInputStream(new byte[][] {getBytes(10, 1), getBytes(0, 0)}, 10);
|
||||
|
||||
assertThat(bis.read(buff, 0, 20)).isEqualTo(10);
|
||||
assertBytes(buff, 0, 10, 1);
|
||||
|
|
@ -106,8 +104,7 @@ public final class BlockInputStreamTest {
|
|||
|
||||
@Test
|
||||
public void testMultipleBlocksEmptyFinalBlock_drain() throws Exception {
|
||||
BlockInputStream bis =
|
||||
new BlockInputStream(new byte[][] {getBytes(10, 1), getBytes(0, 0)}, 10);
|
||||
BlockInputStream bis = new BlockInputStream(new byte[][] {getBytes(10, 1), getBytes(0, 0)}, 10);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bis.drainTo(baos);
|
||||
byte[] data = baos.toByteArray();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.ServerCall;
|
||||
import io.grpc.ServerCallHandler;
|
||||
import io.grpc.Status;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
|
@ -19,11 +23,6 @@ import org.mockito.Mockito;
|
|||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.ServerCall;
|
||||
import io.grpc.ServerCallHandler;
|
||||
import io.grpc.Status;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public final class PendingAuthListenerTest {
|
||||
|
||||
|
|
|
|||
|
|
@ -266,8 +266,7 @@ public final class ServiceBindingTest {
|
|||
@Test
|
||||
@Config(sdk = 30)
|
||||
public void testBindWithTargetUserHandle() throws Exception {
|
||||
binding =
|
||||
newBuilder().setTargetUserHandle(generateUserHandle(/* userId= */ 0)).build();
|
||||
binding = newBuilder().setTargetUserHandle(generateUserHandle(/* userId= */ 0)).build();
|
||||
shadowOf(getMainLooper()).idle();
|
||||
|
||||
binding.bind();
|
||||
|
|
@ -290,8 +289,7 @@ public final class ServiceBindingTest {
|
|||
newBuilder()
|
||||
.setTargetUserHandle(UserHandle.getUserHandleForUid(/* userId= */ 0))
|
||||
.setTargetUserHandle(generateUserHandle(/* userId= */ 0))
|
||||
.setChannelCredentials(
|
||||
BinderChannelCredentials.forDevicePolicyAdmin(adminComponent))
|
||||
.setChannelCredentials(BinderChannelCredentials.forDevicePolicyAdmin(adminComponent))
|
||||
.build();
|
||||
shadowOf(getMainLooper()).idle();
|
||||
|
||||
|
|
@ -317,16 +315,16 @@ public final class ServiceBindingTest {
|
|||
}
|
||||
}
|
||||
|
||||
private static void allowBindDeviceAdminForUser(Context context, ComponentName admin, int userId) {
|
||||
private static void allowBindDeviceAdminForUser(
|
||||
Context context, ComponentName admin, int userId) {
|
||||
ShadowDevicePolicyManager devicePolicyManager =
|
||||
shadowOf(context.getSystemService(DevicePolicyManager.class));
|
||||
devicePolicyManager.setDeviceOwner(admin);
|
||||
devicePolicyManager.setBindDeviceAdminTargetUsers(
|
||||
Arrays.asList(UserHandle.getUserHandleForUid(userId)));
|
||||
shadowOf((DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE));
|
||||
shadowOf((DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE));
|
||||
devicePolicyManager.setDeviceOwner(admin);
|
||||
devicePolicyManager.setBindDeviceAdminTargetUsers(
|
||||
Arrays.asList(generateUserHandle(userId)));
|
||||
devicePolicyManager.setBindDeviceAdminTargetUsers(Arrays.asList(generateUserHandle(userId)));
|
||||
}
|
||||
|
||||
/** Generate UserHandles the hard way. */
|
||||
|
|
@ -373,7 +371,7 @@ public final class ServiceBindingTest {
|
|||
private BinderChannelCredentials channelCredentials = BinderChannelCredentials.forDefault();
|
||||
|
||||
public ServiceBindingBuilder setSourceContext(Context sourceContext) {
|
||||
this.sourceContext = sourceContext;
|
||||
this.sourceContext = sourceContext;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,14 +7,10 @@ import io.grpc.ServerCall;
|
|||
import io.grpc.ServerCallHandler;
|
||||
import io.grpc.ServerInterceptor;
|
||||
|
||||
/**
|
||||
* Class which helps set up {@link PeerUids} to be used in tests.
|
||||
*/
|
||||
/** Class which helps set up {@link PeerUids} to be used in tests. */
|
||||
public final class PeerUidTestHelper {
|
||||
|
||||
/**
|
||||
* The UID of the calling package is set with the value of this key.
|
||||
*/
|
||||
/** The UID of the calling package is set with the value of this key. */
|
||||
public static final Metadata.Key<Integer> UID_KEY =
|
||||
Metadata.Key.of("binder-remote-uid-for-unit-testing", PeerUidTestMarshaller.INSTANCE);
|
||||
|
||||
|
|
@ -41,8 +37,7 @@ public final class PeerUidTestHelper {
|
|||
};
|
||||
}
|
||||
|
||||
private PeerUidTestHelper() {
|
||||
}
|
||||
private PeerUidTestHelper() {}
|
||||
|
||||
private static class PeerUidTestMarshaller implements Metadata.AsciiMarshaller<Integer> {
|
||||
|
||||
|
|
@ -58,6 +53,5 @@ public final class PeerUidTestHelper {
|
|||
return Integer.parseInt(serialized);
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,8 +110,7 @@ public class MainThreadScheduledExecutorService extends AbstractExecutorService
|
|||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
public void shutdown() {}
|
||||
|
||||
@Override
|
||||
public List<Runnable> shutdownNow() {
|
||||
|
|
@ -154,8 +153,7 @@ public class MainThreadScheduledExecutorService extends AbstractExecutorService
|
|||
|
||||
@Override
|
||||
public int compareTo(Delayed other) {
|
||||
return Comparator.comparingLong(
|
||||
(Delayed delayed) -> delayed.getDelay(TimeUnit.MILLISECONDS))
|
||||
return Comparator.comparingLong((Delayed delayed) -> delayed.getDelay(TimeUnit.MILLISECONDS))
|
||||
.compare(this, other);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue