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)
Merged-In: I0aaa0f7f57b8dd137403b6ceb7068e7c99652e1f
Change-Id: I0aaa0f7f57b8dd137403b6ceb7068e7c99652e1f
diff --git a/src/com/android/server/telecom/ConnectionServiceWrapper.java b/src/com/android/server/telecom/ConnectionServiceWrapper.java
index 57b7091..de18d74 100644
--- a/src/com/android/server/telecom/ConnectionServiceWrapper.java
+++ b/src/com/android/server/telecom/ConnectionServiceWrapper.java
@@ -78,6 +78,7 @@
 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;
@@ -1654,11 +1655,21 @@
                         }
                     }
                 };
-                // 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);
+                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(),
@@ -1778,11 +1789,21 @@
                         }
                     }
                 };
-                // 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);
+                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(),