From 241097c6e0768ade8266d1d4ab81c38538204880 Mon Sep 17 00:00:00 2001 From: markb74 <57717302+markb74@users.noreply.github.com> Date: Tue, 29 Nov 2022 09:57:25 +0100 Subject: [PATCH] binder: Set default idle timeout to 60 seconds, and enable "strict lifecycle management". (#9486) --- .../io/grpc/binder/BinderChannelBuilder.java | 22 ++++++++++ .../grpc/binder/BinderChannelBuilderTest.java | 44 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 binder/src/test/java/io/grpc/binder/BinderChannelBuilderTest.java diff --git a/binder/src/main/java/io/grpc/binder/BinderChannelBuilder.java b/binder/src/main/java/io/grpc/binder/BinderChannelBuilder.java index 91e4e8f1c7..8364645a10 100644 --- a/binder/src/main/java/io/grpc/binder/BinderChannelBuilder.java +++ b/binder/src/main/java/io/grpc/binder/BinderChannelBuilder.java @@ -17,6 +17,7 @@ package io.grpc.binder; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; import android.app.Application; import android.content.ComponentName; @@ -124,6 +125,7 @@ public final class BinderChannelBuilder private SecurityPolicy securityPolicy; private InboundParcelablePolicy inboundParcelablePolicy; private BindServiceFlags bindServiceFlags; + private boolean strictLifecycleManagement; private BinderChannelBuilder( @Nullable AndroidComponentAddress directAddress, @@ -164,6 +166,7 @@ public final class BinderChannelBuilder new BinderChannelTransportFactoryBuilder(), null); } + idleTimeout(60, TimeUnit.SECONDS); } @Override @@ -224,6 +227,25 @@ 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. + */ + public BinderChannelBuilder strictLifecycleManagement() { + strictLifecycleManagement = true; + super.idleTimeout(1000, TimeUnit.DAYS); // >30 days disables timeouts entirely. + return this; + } + + @Override + public BinderChannelBuilder idleTimeout(long value, TimeUnit unit) { + checkState(!strictLifecycleManagement, "Idle timeouts are not supported when strict lifecycle management is enabled"); + super.idleTimeout(value, unit); + return this; + } + /** Creates new binder transports. */ private static final class TransportFactory implements ClientTransportFactory { private final Context sourceContext; diff --git a/binder/src/test/java/io/grpc/binder/BinderChannelBuilderTest.java b/binder/src/test/java/io/grpc/binder/BinderChannelBuilderTest.java new file mode 100644 index 0000000000..5dd7e13107 --- /dev/null +++ b/binder/src/test/java/io/grpc/binder/BinderChannelBuilderTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2020 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.binder; + +import static org.junit.Assert.fail; + +import android.content.Context; +import androidx.test.core.app.ApplicationProvider; +import java.util.concurrent.TimeUnit; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public final class BinderChannelBuilderTest { + private final Context appContext = ApplicationProvider.getApplicationContext(); + private final AndroidComponentAddress addr = AndroidComponentAddress.forContext(appContext); + + @Test + public void strictLifecycleManagementForbidsIdleTimers() { + BinderChannelBuilder builder = BinderChannelBuilder.forAddress(addr, appContext); + builder.strictLifecycleManagement(); + try { + builder.idleTimeout(10, TimeUnit.SECONDS); + fail(); + } catch (IllegalStateException ise) { + // Expected. + } + } +}