Loading src/com/android/documentsui/AbstractActionHandler.java +101 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,17 @@ package com.android.documentsui; import static com.android.documentsui.base.DocumentInfo.getCursorInt; import static com.android.documentsui.base.DocumentInfo.getCursorString; import static com.android.documentsui.base.Shared.DEBUG; import android.app.Activity; import android.app.LoaderManager.LoaderCallbacks; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.provider.DocumentsContract; import android.support.annotation.VisibleForTesting; Loading @@ -44,7 +49,6 @@ import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.AnimationView.AnimationType; import com.android.documentsui.dirlist.DocumentDetails; import com.android.documentsui.dirlist.FocusHandler; import com.android.documentsui.dirlist.Model; import com.android.documentsui.files.LauncherActivity; import com.android.documentsui.queries.SearchViewManager; import com.android.documentsui.roots.LoadRootTask; Loading @@ -66,6 +70,9 @@ import javax.annotation.Nullable; public abstract class AbstractActionHandler<T extends Activity & CommonAddons> implements ActionHandler { @VisibleForTesting static final int LOADER_ID = 42; private static final String TAG = "AbstractActionHandler"; private static final int REFRESH_SPINNER_TIMEOUT = 500; Loading @@ -79,8 +86,12 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> protected final Lookup<String, Executor> mExecutors; protected final Injector mInjector; private final LoaderBindings mBindings; private Runnable mDisplayStateChangedListener; private DirectoryReloadLock mDirectoryReloadLock; @Override public void registerDisplayStateChangedListener(Runnable l) { mDisplayStateChangedListener = l; Loading Loading @@ -117,6 +128,8 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> mSearchMgr = searchMgr; mExecutors = executors; mInjector = injector; mBindings = new LoaderBindings(); } @Override Loading Loading @@ -242,6 +255,18 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> throw new UnsupportedOperationException("Show chooser for doc not supported!"); } @Override public void openRootDocument(@Nullable DocumentInfo rootDoc) { if (rootDoc == null) { // There are 2 cases where rootDoc is null -- 1) loading recents; 2) failed to load root // document. Either case we should call refreshCurrentRootAndDirectory() to let // DirectoryFragment update UI. mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } else { openContainerDocument(rootDoc); } } @Override public void openContainerDocument(DocumentInfo doc) { assert(doc.isContainer()); Loading Loading @@ -346,6 +371,22 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> .executeOnExecutor(mExecutors.lookup(uri.getAuthority())); } @Override public void loadDocumentsForCurrentStack() { DocumentStack stack = mState.stack; if (!stack.isRecents() && stack.isEmpty()) { DirectoryResult result = new DirectoryResult(); // TODO (b/35996595): Consider plumbing through the actual exception, though it might // not be very useful (always pointing to DatabaseUtils#readExceptionFromParcel()). result.exception = new IllegalStateException("Failed to load root document."); mInjector.getModel().update(result); return; } mActivity.getLoaderManager().restartLoader(LOADER_ID, null, mBindings); } protected final boolean launchToDocument(Uri uri) { // We don't support launching to a document in an archive. if (!Providers.isArchiveUri(uri)) { Loading Loading @@ -385,6 +426,65 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> return mSelectionMgr.getSelection(new Selection()); } public ActionHandler reset(DirectoryReloadLock reloadLock) { mDirectoryReloadLock = reloadLock; mActivity.getLoaderManager().destroyLoader(LOADER_ID); return this; } private final class LoaderBindings implements LoaderCallbacks<DirectoryResult> { @Override public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { Context context = mActivity; if (mState.stack.isRecents()) { if (DEBUG) Log.d(TAG, "Creating new loader recents."); return new RecentsLoader(context, mRoots, mState, mInjector.features); } else { Uri contentsUri = mSearchMgr.isSearching() ? DocumentsContract.buildSearchDocumentsUri( mState.stack.getRoot().authority, mState.stack.getRoot().rootId, mSearchMgr.getCurrentSearch()) : DocumentsContract.buildChildDocumentsUri( mState.stack.peek().authority, mState.stack.peek().documentId); if (mInjector.config.managedModeEnabled(mState.stack)) { contentsUri = DocumentsContract.setManageMode(contentsUri); } if (DEBUG) Log.d(TAG, "Creating new directory loader for: " + DocumentInfo.debugString(mState.stack.peek())); return new DirectoryLoader( context, mState.stack.getRoot(), mState.stack.peek(), contentsUri, mState.sortModel, mDirectoryReloadLock, mSearchMgr.isSearching()); } } @Override public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { if (DEBUG) Log.d(TAG, "Loader has finished for: " + DocumentInfo.debugString(mState.stack.peek())); assert(result != null); mInjector.getModel().update(result); } @Override public void onLoaderReset(Loader<DirectoryResult> loader) {} } /** * A class primarily for the support of isolating our tests * from our concrete activity implementations. Loading src/com/android/documentsui/ActionHandler.java +6 −3 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.DocumentStack; import com.android.documentsui.base.RootInfo; import com.android.documentsui.dirlist.DocumentDetails; import com.android.documentsui.dirlist.Model; import javax.annotation.Nullable; Loading Loading @@ -84,6 +83,8 @@ public interface ActionHandler { void showChooserForDoc(DocumentInfo doc); void openRootDocument(@Nullable DocumentInfo rootDoc); void openContainerDocument(DocumentInfo doc); void cutToClipboard(); Loading @@ -107,9 +108,11 @@ public interface ActionHandler { void registerDisplayStateChangedListener(Runnable l); void unregisterDisplayStateChangedListener(Runnable l); void loadDocumentsForCurrentStack(); /** * Allow action handler to be initialized in a new scope. * @return * @return this */ <T extends ActionHandler> T reset(Model model); <T extends ActionHandler> T reset(DirectoryReloadLock reloadLock); } src/com/android/documentsui/BaseActivity.java +6 −13 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static com.android.documentsui.base.State.MODE_GRID; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; Loading @@ -32,7 +31,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.MessageQueue.IdleHandler; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Root; import android.support.annotation.CallSuper; import android.support.annotation.LayoutRes; import android.support.annotation.Nullable; Loading @@ -52,7 +50,6 @@ import com.android.documentsui.base.State; import com.android.documentsui.base.State.ViewMode; import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.DocumentsAdapter; import com.android.documentsui.prefs.LocalPreferences; import com.android.documentsui.prefs.PreferencesMonitor; import com.android.documentsui.queries.DebugCommandProcessor; Loading Loading @@ -155,7 +152,11 @@ public abstract class BaseActivity */ @Override public void onSearchChanged(@Nullable String query) { reloadSearch(query); if (query != null) { Metrics.logUserAction(BaseActivity.this, Metrics.USER_ACTION_SEARCH); } mInjector.actions.loadDocumentsForCurrentStack(); } @Override Loading Loading @@ -302,7 +303,7 @@ public abstract class BaseActivity new GetRootDocumentTask( root, this, mInjector.actions::openContainerDocument) mInjector.actions::openRootDocument) .executeOnExecutor(getExecutorForCurrentDirectory()); } } Loading Loading @@ -405,14 +406,6 @@ public abstract class BaseActivity invalidateOptionsMenu(); } private void reloadSearch(String query) { FragmentManager fm = getFragmentManager(); RootInfo root = getCurrentRoot(); DocumentInfo cwd = getCurrentDirectory(); DirectoryFragment.reloadSearch(fm, root, cwd, query); } private final List<String> getExcludedAuthorities() { List<String> authorities = new ArrayList<>(); if (getIntent().getBooleanExtra(DocumentsContract.EXTRA_EXCLUDE_SELF, false)) { Loading src/com/android/documentsui/DirectoryLoader.java +2 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; import android.os.OperationCanceledException; import android.os.RemoteException; import android.provider.DocumentsContract.Document; Loading Loading @@ -220,7 +221,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { private final Runnable mContentChangedCallback; public LockingContentObserver(DirectoryReloadLock lock, Runnable contentChangedCallback) { super(new Handler()); super(new Handler(Looper.getMainLooper())); mLock = lock; mContentChangedCallback = contentChangedCallback; } Loading src/com/android/documentsui/DragShadowBuilder.java +0 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.widget.TextView; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.Shared; import com.android.documentsui.dirlist.IconHelper; import com.android.documentsui.dirlist.Model; import com.android.documentsui.selection.Selection; import java.util.List; Loading Loading
src/com/android/documentsui/AbstractActionHandler.java +101 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,17 @@ package com.android.documentsui; import static com.android.documentsui.base.DocumentInfo.getCursorInt; import static com.android.documentsui.base.DocumentInfo.getCursorString; import static com.android.documentsui.base.Shared.DEBUG; import android.app.Activity; import android.app.LoaderManager.LoaderCallbacks; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.provider.DocumentsContract; import android.support.annotation.VisibleForTesting; Loading @@ -44,7 +49,6 @@ import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.AnimationView.AnimationType; import com.android.documentsui.dirlist.DocumentDetails; import com.android.documentsui.dirlist.FocusHandler; import com.android.documentsui.dirlist.Model; import com.android.documentsui.files.LauncherActivity; import com.android.documentsui.queries.SearchViewManager; import com.android.documentsui.roots.LoadRootTask; Loading @@ -66,6 +70,9 @@ import javax.annotation.Nullable; public abstract class AbstractActionHandler<T extends Activity & CommonAddons> implements ActionHandler { @VisibleForTesting static final int LOADER_ID = 42; private static final String TAG = "AbstractActionHandler"; private static final int REFRESH_SPINNER_TIMEOUT = 500; Loading @@ -79,8 +86,12 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> protected final Lookup<String, Executor> mExecutors; protected final Injector mInjector; private final LoaderBindings mBindings; private Runnable mDisplayStateChangedListener; private DirectoryReloadLock mDirectoryReloadLock; @Override public void registerDisplayStateChangedListener(Runnable l) { mDisplayStateChangedListener = l; Loading Loading @@ -117,6 +128,8 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> mSearchMgr = searchMgr; mExecutors = executors; mInjector = injector; mBindings = new LoaderBindings(); } @Override Loading Loading @@ -242,6 +255,18 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> throw new UnsupportedOperationException("Show chooser for doc not supported!"); } @Override public void openRootDocument(@Nullable DocumentInfo rootDoc) { if (rootDoc == null) { // There are 2 cases where rootDoc is null -- 1) loading recents; 2) failed to load root // document. Either case we should call refreshCurrentRootAndDirectory() to let // DirectoryFragment update UI. mActivity.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } else { openContainerDocument(rootDoc); } } @Override public void openContainerDocument(DocumentInfo doc) { assert(doc.isContainer()); Loading Loading @@ -346,6 +371,22 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> .executeOnExecutor(mExecutors.lookup(uri.getAuthority())); } @Override public void loadDocumentsForCurrentStack() { DocumentStack stack = mState.stack; if (!stack.isRecents() && stack.isEmpty()) { DirectoryResult result = new DirectoryResult(); // TODO (b/35996595): Consider plumbing through the actual exception, though it might // not be very useful (always pointing to DatabaseUtils#readExceptionFromParcel()). result.exception = new IllegalStateException("Failed to load root document."); mInjector.getModel().update(result); return; } mActivity.getLoaderManager().restartLoader(LOADER_ID, null, mBindings); } protected final boolean launchToDocument(Uri uri) { // We don't support launching to a document in an archive. if (!Providers.isArchiveUri(uri)) { Loading Loading @@ -385,6 +426,65 @@ public abstract class AbstractActionHandler<T extends Activity & CommonAddons> return mSelectionMgr.getSelection(new Selection()); } public ActionHandler reset(DirectoryReloadLock reloadLock) { mDirectoryReloadLock = reloadLock; mActivity.getLoaderManager().destroyLoader(LOADER_ID); return this; } private final class LoaderBindings implements LoaderCallbacks<DirectoryResult> { @Override public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { Context context = mActivity; if (mState.stack.isRecents()) { if (DEBUG) Log.d(TAG, "Creating new loader recents."); return new RecentsLoader(context, mRoots, mState, mInjector.features); } else { Uri contentsUri = mSearchMgr.isSearching() ? DocumentsContract.buildSearchDocumentsUri( mState.stack.getRoot().authority, mState.stack.getRoot().rootId, mSearchMgr.getCurrentSearch()) : DocumentsContract.buildChildDocumentsUri( mState.stack.peek().authority, mState.stack.peek().documentId); if (mInjector.config.managedModeEnabled(mState.stack)) { contentsUri = DocumentsContract.setManageMode(contentsUri); } if (DEBUG) Log.d(TAG, "Creating new directory loader for: " + DocumentInfo.debugString(mState.stack.peek())); return new DirectoryLoader( context, mState.stack.getRoot(), mState.stack.peek(), contentsUri, mState.sortModel, mDirectoryReloadLock, mSearchMgr.isSearching()); } } @Override public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { if (DEBUG) Log.d(TAG, "Loader has finished for: " + DocumentInfo.debugString(mState.stack.peek())); assert(result != null); mInjector.getModel().update(result); } @Override public void onLoaderReset(Loader<DirectoryResult> loader) {} } /** * A class primarily for the support of isolating our tests * from our concrete activity implementations. Loading
src/com/android/documentsui/ActionHandler.java +6 −3 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.DocumentStack; import com.android.documentsui.base.RootInfo; import com.android.documentsui.dirlist.DocumentDetails; import com.android.documentsui.dirlist.Model; import javax.annotation.Nullable; Loading Loading @@ -84,6 +83,8 @@ public interface ActionHandler { void showChooserForDoc(DocumentInfo doc); void openRootDocument(@Nullable DocumentInfo rootDoc); void openContainerDocument(DocumentInfo doc); void cutToClipboard(); Loading @@ -107,9 +108,11 @@ public interface ActionHandler { void registerDisplayStateChangedListener(Runnable l); void unregisterDisplayStateChangedListener(Runnable l); void loadDocumentsForCurrentStack(); /** * Allow action handler to be initialized in a new scope. * @return * @return this */ <T extends ActionHandler> T reset(Model model); <T extends ActionHandler> T reset(DirectoryReloadLock reloadLock); }
src/com/android/documentsui/BaseActivity.java +6 −13 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import static com.android.documentsui.base.State.MODE_GRID; import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; Loading @@ -32,7 +31,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.MessageQueue.IdleHandler; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Root; import android.support.annotation.CallSuper; import android.support.annotation.LayoutRes; import android.support.annotation.Nullable; Loading @@ -52,7 +50,6 @@ import com.android.documentsui.base.State; import com.android.documentsui.base.State.ViewMode; import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.DocumentsAdapter; import com.android.documentsui.prefs.LocalPreferences; import com.android.documentsui.prefs.PreferencesMonitor; import com.android.documentsui.queries.DebugCommandProcessor; Loading Loading @@ -155,7 +152,11 @@ public abstract class BaseActivity */ @Override public void onSearchChanged(@Nullable String query) { reloadSearch(query); if (query != null) { Metrics.logUserAction(BaseActivity.this, Metrics.USER_ACTION_SEARCH); } mInjector.actions.loadDocumentsForCurrentStack(); } @Override Loading Loading @@ -302,7 +303,7 @@ public abstract class BaseActivity new GetRootDocumentTask( root, this, mInjector.actions::openContainerDocument) mInjector.actions::openRootDocument) .executeOnExecutor(getExecutorForCurrentDirectory()); } } Loading Loading @@ -405,14 +406,6 @@ public abstract class BaseActivity invalidateOptionsMenu(); } private void reloadSearch(String query) { FragmentManager fm = getFragmentManager(); RootInfo root = getCurrentRoot(); DocumentInfo cwd = getCurrentDirectory(); DirectoryFragment.reloadSearch(fm, root, cwd, query); } private final List<String> getExcludedAuthorities() { List<String> authorities = new ArrayList<>(); if (getIntent().getBooleanExtra(DocumentsContract.EXTRA_EXCLUDE_SELF, false)) { Loading
src/com/android/documentsui/DirectoryLoader.java +2 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.CancellationSignal; import android.os.Handler; import android.os.Looper; import android.os.OperationCanceledException; import android.os.RemoteException; import android.provider.DocumentsContract.Document; Loading Loading @@ -220,7 +221,7 @@ public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> { private final Runnable mContentChangedCallback; public LockingContentObserver(DirectoryReloadLock lock, Runnable contentChangedCallback) { super(new Handler()); super(new Handler(Looper.getMainLooper())); mLock = lock; mContentChangedCallback = contentChangedCallback; } Loading
src/com/android/documentsui/DragShadowBuilder.java +0 −1 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ import android.widget.TextView; import com.android.documentsui.base.DocumentInfo; import com.android.documentsui.base.Shared; import com.android.documentsui.dirlist.IconHelper; import com.android.documentsui.dirlist.Model; import com.android.documentsui.selection.Selection; import java.util.List; Loading