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

Commit 340189fe authored by Zemiao Zhu's avatar Zemiao Zhu Committed by Automerger Merge Worker
Browse files

Fix ANR caused by multiple loaders blocking UI thread. am: a4005b9a

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/DocumentsUI/+/13293494

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I050b549665c3f4e915dbe6a15331741ea72274b9
parents 06ea049e a4005b9a
Loading
Loading
Loading
Loading
+13 −2
Original line number Original line Diff line number Diff line
@@ -76,6 +76,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.List;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.function.Consumer;
import java.util.function.Consumer;


import javax.annotation.Nullable;
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 String TAG = "AbstractActionHandler";
    private static final int REFRESH_SPINNER_TIMEOUT = 500;
    private static final int REFRESH_SPINNER_TIMEOUT = 500;
    private final Semaphore mLoaderSemaphore = new Semaphore(1);


    protected final T mActivity;
    protected final T mActivity;
    protected final State mState;
    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 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.
        // 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);
            mActivity.getSupportLoaderManager().restartLoader(LOADER_ID, null, mBindings);
        }
        }
    }


    protected final boolean launchToDocument(Uri uri) {
    protected final boolean launchToDocument(Uri uri) {
        // We don't support launching to a document in an archive.
        // 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);
            assert(result != null);


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


        @Override
        @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
     * A class primarily for the support of isolating our tests