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

Commit a4005b9a authored by Zemiao Zhu's avatar Zemiao Zhu
Browse files

Fix ANR caused by multiple loaders blocking UI thread.

Fix: 162477640
Test: atest DocumentsUIGoogleTests
Change-Id: I384f97ee1c0e69141d6d7f48c3136801ee96a555
parent 47e3f4f1
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.function.Consumer;

import javax.annotation.Nullable;
@@ -94,6 +95,7 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA

    private static final String TAG = "AbstractActionHandler";
    private static final int REFRESH_SPINNER_TIMEOUT = 500;
    private final Semaphore mLoaderSemaphore = new Semaphore(1);

    protected final T mActivity;
    protected final State mState;
@@ -767,8 +769,14 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
        // For RecentsLoader and GlobalSearchLoader, they do not require rootDoc so it is no-op.
        // For DirectoryLoader, the loader needs to handle the case when stack.peek() returns null.

        // Only allow restartLoader when the previous loader is finished or reset. Allowing
        // multiple consecutive calls to restartLoader() / onCreateLoader() will probably create
        // multiple active loaders, because restartLoader() does not interrupt previous loaders'
        // loading, therefore may block the UI thread and cause ANR.
        if (mLoaderSemaphore.tryAcquire()) {
            mActivity.getSupportLoaderManager().restartLoader(LOADER_ID, null, mBindings);
        }
    }

    protected final boolean launchToDocument(Uri uri) {
        // We don't support launching to a document in an archive.
@@ -942,10 +950,13 @@ public abstract class AbstractActionHandler<T extends FragmentActivity & CommonA
            assert(result != null);

            mInjector.getModel().update(result);
            mLoaderSemaphore.release();
        }

        @Override
        public void onLoaderReset(Loader<DirectoryResult> loader) {}
        public void onLoaderReset(Loader<DirectoryResult> loader) {
            mLoaderSemaphore.release();
        }
    }
    /**
     * A class primarily for the support of isolating our tests