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

Commit 6068c5a5 authored by Omar Eissa's avatar Omar Eissa
Browse files

Don't start binding to remote ExternalStorageService in some flows

In case we try to end fuse session or notifying volume state changes, we
try to bind even if we haven't managed to bind to the remote
ExternalStorageService before. In such cases, there is no need to bring
up the remote service as this situation means that we didn't actually
start a session before, or the service has died. In both of these cases,
when the remote service comes up later, we will make sure that
everything is reset, so that we start over the mounting process and
hence notify the correct state. The current logic will unnecessarily
wait for long time to bring the service up to notify stale events or end
a session that won't be there anyway as the remote service wasn't started
before or died at some time later.

Additionally, reduce the timeout time to 10 seconds in the above cases
as we no longer wait for service binding.

Bug: 369519866
Test: Manual & atest StorageManagerTest
Flag: EXEMPT bufix
Change-Id: I5233167e842ee8e8625d0c44e461b45a4577559c
parent d9f8e5f2
Loading
Loading
Loading
Loading
+34 −6
Original line number Diff line number Diff line
@@ -351,18 +351,38 @@ public final class StorageUserConnection {
            }
        }


        private void waitForAsyncVoid(AsyncStorageServiceCall asyncCall) throws Exception {
            waitForAsyncVoid(asyncCall, /*bindIfNotConnected*/ true,
                    DEFAULT_REMOTE_TIMEOUT_SECONDS);
        }

        private void waitForAsyncVoid(AsyncStorageServiceCall asyncCall,
                boolean bindIfNotConnected, int timeoutSeconds) throws Exception {
            CompletableFuture<Void> opFuture = new CompletableFuture<>();
            RemoteCallback callback = new RemoteCallback(result -> setResult(result, opFuture));

            waitForAsync(asyncCall, callback, opFuture, mOutstandingOps,
                    DEFAULT_REMOTE_TIMEOUT_SECONDS);
            waitForAsync(asyncCall, callback, opFuture, mOutstandingOps, bindIfNotConnected,
                    timeoutSeconds);
        }

        private <T> T waitForAsync(AsyncStorageServiceCall asyncCall, RemoteCallback callback,
                CompletableFuture<T> opFuture, ArrayList<CompletableFuture<T>> outstandingOps,
                long timeoutSeconds) throws Exception {
            CompletableFuture<IExternalStorageService> serviceFuture = connectIfNeeded();
                boolean bindIfNotConnected, long timeoutSeconds) throws Exception {

            CompletableFuture<IExternalStorageService> serviceFuture;
            if (bindIfNotConnected) {
                serviceFuture = connectIfNeeded();
            } else {
                synchronized (mLock) {
                    if (mRemoteFuture == null || mRemoteFuture.getNow(null) == null) {
                        Slog.w(TAG, "Dropping async request as service is not connected"
                                + "and request doesn't require connecting");
                        return null;
                    }
                    serviceFuture = mRemoteFuture;
                }
            }

            try {
                synchronized (mLock) {
@@ -404,7 +424,11 @@ public final class StorageUserConnection {
        public void endSession(Session session) throws ExternalStorageServiceException {
            try {
                waitForAsyncVoid((service, callback) ->
                        service.endSession(session.sessionId, callback));
                        service.endSession(session.sessionId, callback),
                        // endSession shouldn't be trying to bind to remote service if the service
                        // isn't connected already as this means that no previous mounting has been
                        // completed.
                        /*bindIfNotConnected*/ false, /*timeoutSeconds*/ 10);
            } catch (Exception e) {
                throw new ExternalStorageServiceException("Failed to end session: " + session, e);
            }
@@ -415,7 +439,11 @@ public final class StorageUserConnection {
                ExternalStorageServiceException {
            try {
                waitForAsyncVoid((service, callback) ->
                        service.notifyVolumeStateChanged(sessionId, vol, callback));
                        service.notifyVolumeStateChanged(sessionId, vol, callback),
                        // notifyVolumeStateChanged shouldn't be trying to bind to remote service
                        // if the service isn't connected already as this means that
                        // no previous mounting has been completed
                        /*bindIfNotConnected*/ false, /*timeoutSeconds*/ 10);
            } catch (Exception e) {
                throw new ExternalStorageServiceException("Failed to notify volume state changed "
                        + "for vol : " + vol, e);