Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64434f71 authored by Grant Menke's avatar Grant Menke Committed by Markus S
Browse files

Ensure ScheduledExecutor is not shutdown before scheduling timeout cleanup.

The scheduled executor in ConnectionServiceWrapper may be shutdown when calling createConference and
 createCall. This is infrequently causing a `RejectedExecutionException`. This CL adds a check that
mScheduledExecutor is not shutdown before scheduling the cleanup.

Flag: EXEMPT Security High/Critical Severity CVE
Bug: 388588560
Test: manually using the provided apk + atest CallsManagerTest
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:dd63d318cf090ca2d458f772e2799614e6068006)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ef6f10655531a06d2814c3fad25eb7cd1e117581)
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5f4dfa3ead83c0b1eb9999b0389468d28347d167)
Merged-In: I0aaa0f7f57b8dd137403b6ceb7068e7c99652e1f
Change-Id: I0aaa0f7f57b8dd137403b6ceb7068e7c99652e1f
parent 445dd84a
Loading
Loading
Loading
Loading
+31 −10
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -1304,11 +1305,21 @@ public class ConnectionServiceWrapper extends ServiceBinder implements
                                }
                            }
                        };
                // Post cleanup to the executor service and cache the future, so we can cancel it if
                // needed.
                ScheduledFuture<?> future = mScheduledExecutor.schedule(r.getRunnableToCancel(),
                        SERVICE_BINDING_TIMEOUT, TimeUnit.MILLISECONDS);
                if (mScheduledExecutor != null && !mScheduledExecutor.isShutdown()) {
                    try {
                        // Post cleanup to the executor service and cache the future,
                        // so we can cancel it if needed.
                        ScheduledFuture<?> future = mScheduledExecutor.schedule(
                                r.getRunnableToCancel(),SERVICE_BINDING_TIMEOUT,
                                TimeUnit.MILLISECONDS);
                        mScheduledFutureMap.put(call, future);
                    } catch (RejectedExecutionException e) {
                        Log.e(this, e, "createConference: mScheduledExecutor was "
                                + "already shutdown");
                    }
                } else {
                    Log.w(this, "createConference: Scheduled executor is null or shutdown");
                }
                try {
                    mServiceInterface.createConference(
                            call.getConnectionManagerPhoneAccount(),
@@ -1413,11 +1424,21 @@ public class ConnectionServiceWrapper extends ServiceBinder implements
                                }
                            }
                        };
                // Post cleanup to the executor service and cache the future, so we can cancel it if
                // needed.
                ScheduledFuture<?> future = mScheduledExecutor.schedule(r.getRunnableToCancel(),
                        SERVICE_BINDING_TIMEOUT, TimeUnit.MILLISECONDS);
                if (mScheduledExecutor != null && !mScheduledExecutor.isShutdown()) {
                    try {
                        // Post cleanup to the executor service and cache the future,
                        // so we can cancel it if needed.
                        ScheduledFuture<?> future = mScheduledExecutor.schedule(
                                r.getRunnableToCancel(),SERVICE_BINDING_TIMEOUT,
                                TimeUnit.MILLISECONDS);
                        mScheduledFutureMap.put(call, future);
                    } catch (RejectedExecutionException e) {
                        Log.e(this, e, "createConnection: mScheduledExecutor was "
                                + "already shutdown");
                    }
                } else {
                    Log.w(this, "createConnection: Scheduled executor is null or shutdown");
                }
                try {
                    mServiceInterface.createConnection(
                            call.getConnectionManagerPhoneAccount(),