Loading src/com/android/documentsui/AbstractActionHandler.java +13 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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 Loading Loading
src/com/android/documentsui/AbstractActionHandler.java +13 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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 Loading