Loading packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +0 −3 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; Loading Loading @@ -74,8 +73,6 @@ public class DocumentsActivity extends BaseActivity { public void onCreate(Bundle icicle) { super.onCreate(icicle); final Resources res = getResources(); if (mState.action == ACTION_CREATE) { final String mimeType = getIntent().getType(); final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE); Loading packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +26 −26 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public class RootsCache { private final ContentObserver mObserver; private OnCacheUpdateListener mCacheUpdateListener; private final RootInfo mRecentsRoot = new RootInfo(); private final RootInfo mRecentsRoot; private final Object mLock = new Object(); private final CountDownLatch mFirstLoad = new CountDownLatch(1); Loading @@ -82,6 +82,18 @@ public class RootsCache { public RootsCache(Context context) { mContext = context; mObserver = new RootsChangedObserver(); // Create a new anonymous "Recents" RootInfo. It's a faker. mRecentsRoot = new RootInfo() {{ // Special root for recents authority = null; rootId = null; derivedIcon = R.drawable.ic_root_recent; derivedType = RootInfo.TYPE_RECENTS; flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD; title = mContext.getString(R.string.root_recent); availableBytes = -1; }}; } private class RootsChangedObserver extends ContentObserver { Loading @@ -104,16 +116,6 @@ public class RootsCache { * Gather roots from all known storage providers. */ public void updateAsync() { // Special root for recents mRecentsRoot.authority = null; mRecentsRoot.rootId = null; mRecentsRoot.derivedIcon = R.drawable.ic_root_recent; mRecentsRoot.derivedType = RootInfo.TYPE_RECENTS; mRecentsRoot.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD; mRecentsRoot.title = mContext.getString(R.string.root_recent); mRecentsRoot.availableBytes = -1; new UpdateTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } Loading Loading @@ -360,7 +362,7 @@ public class RootsCache { } public boolean isRecentsRoot(RootInfo root) { return mRecentsRoot == root; return mRecentsRoot.equals(root); } public Collection<RootInfo> getRootsBlocking() { Loading Loading @@ -400,27 +402,22 @@ public class RootsCache { static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) { final List<RootInfo> matching = new ArrayList<>(); for (RootInfo root : roots) { final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0; final boolean supportsIsChild = (root.flags & Root.FLAG_SUPPORTS_IS_CHILD) != 0; final boolean advanced = (root.flags & Root.FLAG_ADVANCED) != 0; final boolean localOnly = (root.flags & Root.FLAG_LOCAL_ONLY) != 0; final boolean empty = (root.flags & Root.FLAG_EMPTY) != 0; // Exclude read-only devices when creating if (state.action == State.ACTION_CREATE && !supportsCreate) continue; if (state.action == State.ACTION_PICK_COPY_DESTINATION && !supportsCreate) continue; if (state.action == State.ACTION_CREATE && !root.supportsCreate()) continue; if (state.action == State.ACTION_PICK_COPY_DESTINATION && !root.supportsCreate()) continue; // Exclude roots that don't support directory picking if (state.action == State.ACTION_OPEN_TREE && !supportsIsChild) continue; if (state.action == State.ACTION_OPEN_TREE && !root.supportsChildren()) continue; // Exclude advanced devices when not requested if (!state.showAdvanced && advanced) continue; if (!state.showAdvanced && root.isAdvanced()) continue; // Exclude non-local devices when local only if (state.localOnly && !localOnly) continue; if (state.localOnly && !root.isLocalOnly()) continue; // Exclude downloads roots that don't support directory creation // TODO: Add flag to check the root supports directory creation or not. if (state.directoryCopy && root.isDownloads()) continue; if (state.directoryCopy && !root.supportsChildren()) continue; // Only show empty roots when creating, or in browse mode. if (empty && (state.action == State.ACTION_OPEN if (root.isEmpty() && (state.action == State.ACTION_OPEN || state.action == State.ACTION_GET_CONTENT)) { if (DEBUG) Log.i(TAG, "Skipping empty root: " + root); continue; Loading @@ -436,10 +433,13 @@ public class RootsCache { // Exclude roots from the calling package. if (state.excludedAuthorities.contains(root.authority)) { if (DEBUG) Log.d(TAG, "Excluding root " + root.authority + " from calling package."); if (DEBUG) Log.d( TAG, "Excluding root " + root.authority + " from calling package."); continue; } if (DEBUG) Log.d( TAG, "Including root " + root + " in roots list."); matching.add(root); } return matching; Loading packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java +44 −22 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.annotation.Nullable; import android.text.TextUtils; import android.text.format.Formatter; import android.util.Log; Loading Loading @@ -86,7 +87,6 @@ public class RootsFragment extends Fragment { @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final Context context = inflater.getContext(); final View view = inflater.inflate(R.layout.fragment_roots, container, false); mList = (ListView) view.findViewById(R.id.roots_list); Loading @@ -112,11 +112,13 @@ public class RootsFragment extends Fragment { @Override public void onLoadFinished( Loader<Collection<RootInfo>> loader, Collection<RootInfo> result) { if (!isAdded()) return; if (!isAdded()) { return; } final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); Intent handlerAppIntent = getArguments().getParcelable(EXTRA_INCLUDE_APPS); mAdapter = new RootsAdapter(context, result, includeApps); mAdapter = new RootsAdapter(context, result, handlerAppIntent); mList.setAdapter(mAdapter); onCurrentRootChanged(); Loading Loading @@ -151,7 +153,9 @@ public class RootsFragment extends Fragment { } public void onCurrentRootChanged() { if (mAdapter == null) return; if (mAdapter == null) { return; } final RootInfo root = ((BaseActivity) getActivity()).getCurrentRoot(); for (int i = 0; i < mAdapter.getCount(); i++) { Loading Loading @@ -300,7 +304,13 @@ public class RootsFragment extends Fragment { } private static class RootsAdapter extends ArrayAdapter<Item> { public RootsAdapter(Context context, Collection<RootInfo> roots, Intent includeApps) { /** * @param handlerAppIntent When not null, apps capable of handling the original * intent will be included in list of roots (in special section at bottom). */ public RootsAdapter( Context context, Collection<RootInfo> roots, @Nullable Intent handlerAppIntent) { super(context, 0); final List<RootItem> libraries = new ArrayList<>(); Loading @@ -322,13 +332,26 @@ public class RootsFragment extends Fragment { Collections.sort(others, comp); addAll(libraries); // Only add the spacer if it is actually separating something. if (!libraries.isEmpty() && !others.isEmpty()) { add(new SpacerItem()); } addAll(others); if (includeApps != null) { // Include apps that can handle this intent too. if (handlerAppIntent != null) { includeHandlerApps(context, handlerAppIntent); } } /** * Adds apps capable of handling the original intent will be included * in list of roots (in special section at bottom). */ private void includeHandlerApps(Context context, Intent handlerAppIntent) { final PackageManager pm = context.getPackageManager(); final List<ResolveInfo> infos = pm.queryIntentActivities( includeApps, PackageManager.MATCH_DEFAULT_ONLY); handlerAppIntent, PackageManager.MATCH_DEFAULT_ONLY); final List<AppItem> apps = new ArrayList<>(); Loading @@ -344,7 +367,6 @@ public class RootsFragment extends Fragment { addAll(apps); } } } @Override public View getView(int position, View convertView, ViewGroup parent) { Loading packages/DocumentsUI/src/com/android/documentsui/RootsLoader.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class RootsLoader extends AsyncTaskLoader<Collection<RootInfo>> { if (isReset()) { return; } Collection<RootInfo> oldResult = mResult; mResult = result; if (isStarted()) { Loading packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +9 −8 Original line number Diff line number Diff line Loading @@ -985,7 +985,8 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } private void copyDocuments(final List<DocumentInfo> docs, final DocumentInfo destination) { if (!canCopy(docs, destination)) { BaseActivity activity = (BaseActivity) getActivity(); if (!canCopy(docs, activity.getCurrentRoot(), destination)) { Snackbars.makeSnackbar( getActivity(), R.string.clipboard_files_cannot_paste, Loading Loading @@ -1065,13 +1066,13 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi * * @return true if the list of files can be copied to destination. */ boolean canCopy(List<DocumentInfo> files, DocumentInfo dest) { BaseActivity activity = (BaseActivity) getActivity(); final RootInfo root = activity.getCurrentRoot(); private boolean canCopy(List<DocumentInfo> files, RootInfo root, DocumentInfo dest) { if (dest == null || !dest.isDirectory() || !dest.isCreateSupported()) { return false; } // Can't copy folders to Downloads. if (root.isDownloads()) { // Can't copy folders to roots that don't support children. if (!root.supportsChildren()) { for (DocumentInfo docs : files) { if (docs.isDirectory()) { return false; Loading @@ -1079,7 +1080,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } } return dest != null && dest.isDirectory() && dest.isCreateSupported(); return true; } public void selectAllFiles() { Loading Loading
packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +0 −3 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; Loading Loading @@ -74,8 +73,6 @@ public class DocumentsActivity extends BaseActivity { public void onCreate(Bundle icicle) { super.onCreate(icicle); final Resources res = getResources(); if (mState.action == ACTION_CREATE) { final String mimeType = getIntent().getType(); final String title = getIntent().getStringExtra(Intent.EXTRA_TITLE); Loading
packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +26 −26 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public class RootsCache { private final ContentObserver mObserver; private OnCacheUpdateListener mCacheUpdateListener; private final RootInfo mRecentsRoot = new RootInfo(); private final RootInfo mRecentsRoot; private final Object mLock = new Object(); private final CountDownLatch mFirstLoad = new CountDownLatch(1); Loading @@ -82,6 +82,18 @@ public class RootsCache { public RootsCache(Context context) { mContext = context; mObserver = new RootsChangedObserver(); // Create a new anonymous "Recents" RootInfo. It's a faker. mRecentsRoot = new RootInfo() {{ // Special root for recents authority = null; rootId = null; derivedIcon = R.drawable.ic_root_recent; derivedType = RootInfo.TYPE_RECENTS; flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_IS_CHILD; title = mContext.getString(R.string.root_recent); availableBytes = -1; }}; } private class RootsChangedObserver extends ContentObserver { Loading @@ -104,16 +116,6 @@ public class RootsCache { * Gather roots from all known storage providers. */ public void updateAsync() { // Special root for recents mRecentsRoot.authority = null; mRecentsRoot.rootId = null; mRecentsRoot.derivedIcon = R.drawable.ic_root_recent; mRecentsRoot.derivedType = RootInfo.TYPE_RECENTS; mRecentsRoot.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_IS_CHILD; mRecentsRoot.title = mContext.getString(R.string.root_recent); mRecentsRoot.availableBytes = -1; new UpdateTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } Loading Loading @@ -360,7 +362,7 @@ public class RootsCache { } public boolean isRecentsRoot(RootInfo root) { return mRecentsRoot == root; return mRecentsRoot.equals(root); } public Collection<RootInfo> getRootsBlocking() { Loading Loading @@ -400,27 +402,22 @@ public class RootsCache { static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) { final List<RootInfo> matching = new ArrayList<>(); for (RootInfo root : roots) { final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0; final boolean supportsIsChild = (root.flags & Root.FLAG_SUPPORTS_IS_CHILD) != 0; final boolean advanced = (root.flags & Root.FLAG_ADVANCED) != 0; final boolean localOnly = (root.flags & Root.FLAG_LOCAL_ONLY) != 0; final boolean empty = (root.flags & Root.FLAG_EMPTY) != 0; // Exclude read-only devices when creating if (state.action == State.ACTION_CREATE && !supportsCreate) continue; if (state.action == State.ACTION_PICK_COPY_DESTINATION && !supportsCreate) continue; if (state.action == State.ACTION_CREATE && !root.supportsCreate()) continue; if (state.action == State.ACTION_PICK_COPY_DESTINATION && !root.supportsCreate()) continue; // Exclude roots that don't support directory picking if (state.action == State.ACTION_OPEN_TREE && !supportsIsChild) continue; if (state.action == State.ACTION_OPEN_TREE && !root.supportsChildren()) continue; // Exclude advanced devices when not requested if (!state.showAdvanced && advanced) continue; if (!state.showAdvanced && root.isAdvanced()) continue; // Exclude non-local devices when local only if (state.localOnly && !localOnly) continue; if (state.localOnly && !root.isLocalOnly()) continue; // Exclude downloads roots that don't support directory creation // TODO: Add flag to check the root supports directory creation or not. if (state.directoryCopy && root.isDownloads()) continue; if (state.directoryCopy && !root.supportsChildren()) continue; // Only show empty roots when creating, or in browse mode. if (empty && (state.action == State.ACTION_OPEN if (root.isEmpty() && (state.action == State.ACTION_OPEN || state.action == State.ACTION_GET_CONTENT)) { if (DEBUG) Log.i(TAG, "Skipping empty root: " + root); continue; Loading @@ -436,10 +433,13 @@ public class RootsCache { // Exclude roots from the calling package. if (state.excludedAuthorities.contains(root.authority)) { if (DEBUG) Log.d(TAG, "Excluding root " + root.authority + " from calling package."); if (DEBUG) Log.d( TAG, "Excluding root " + root.authority + " from calling package."); continue; } if (DEBUG) Log.d( TAG, "Including root " + root + " in roots list."); matching.add(root); } return matching; Loading
packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java +44 −22 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.annotation.Nullable; import android.text.TextUtils; import android.text.format.Formatter; import android.util.Log; Loading Loading @@ -86,7 +87,6 @@ public class RootsFragment extends Fragment { @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final Context context = inflater.getContext(); final View view = inflater.inflate(R.layout.fragment_roots, container, false); mList = (ListView) view.findViewById(R.id.roots_list); Loading @@ -112,11 +112,13 @@ public class RootsFragment extends Fragment { @Override public void onLoadFinished( Loader<Collection<RootInfo>> loader, Collection<RootInfo> result) { if (!isAdded()) return; if (!isAdded()) { return; } final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); Intent handlerAppIntent = getArguments().getParcelable(EXTRA_INCLUDE_APPS); mAdapter = new RootsAdapter(context, result, includeApps); mAdapter = new RootsAdapter(context, result, handlerAppIntent); mList.setAdapter(mAdapter); onCurrentRootChanged(); Loading Loading @@ -151,7 +153,9 @@ public class RootsFragment extends Fragment { } public void onCurrentRootChanged() { if (mAdapter == null) return; if (mAdapter == null) { return; } final RootInfo root = ((BaseActivity) getActivity()).getCurrentRoot(); for (int i = 0; i < mAdapter.getCount(); i++) { Loading Loading @@ -300,7 +304,13 @@ public class RootsFragment extends Fragment { } private static class RootsAdapter extends ArrayAdapter<Item> { public RootsAdapter(Context context, Collection<RootInfo> roots, Intent includeApps) { /** * @param handlerAppIntent When not null, apps capable of handling the original * intent will be included in list of roots (in special section at bottom). */ public RootsAdapter( Context context, Collection<RootInfo> roots, @Nullable Intent handlerAppIntent) { super(context, 0); final List<RootItem> libraries = new ArrayList<>(); Loading @@ -322,13 +332,26 @@ public class RootsFragment extends Fragment { Collections.sort(others, comp); addAll(libraries); // Only add the spacer if it is actually separating something. if (!libraries.isEmpty() && !others.isEmpty()) { add(new SpacerItem()); } addAll(others); if (includeApps != null) { // Include apps that can handle this intent too. if (handlerAppIntent != null) { includeHandlerApps(context, handlerAppIntent); } } /** * Adds apps capable of handling the original intent will be included * in list of roots (in special section at bottom). */ private void includeHandlerApps(Context context, Intent handlerAppIntent) { final PackageManager pm = context.getPackageManager(); final List<ResolveInfo> infos = pm.queryIntentActivities( includeApps, PackageManager.MATCH_DEFAULT_ONLY); handlerAppIntent, PackageManager.MATCH_DEFAULT_ONLY); final List<AppItem> apps = new ArrayList<>(); Loading @@ -344,7 +367,6 @@ public class RootsFragment extends Fragment { addAll(apps); } } } @Override public View getView(int position, View convertView, ViewGroup parent) { Loading
packages/DocumentsUI/src/com/android/documentsui/RootsLoader.java +1 −1 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public class RootsLoader extends AsyncTaskLoader<Collection<RootInfo>> { if (isReset()) { return; } Collection<RootInfo> oldResult = mResult; mResult = result; if (isStarted()) { Loading
packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +9 −8 Original line number Diff line number Diff line Loading @@ -985,7 +985,8 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } private void copyDocuments(final List<DocumentInfo> docs, final DocumentInfo destination) { if (!canCopy(docs, destination)) { BaseActivity activity = (BaseActivity) getActivity(); if (!canCopy(docs, activity.getCurrentRoot(), destination)) { Snackbars.makeSnackbar( getActivity(), R.string.clipboard_files_cannot_paste, Loading Loading @@ -1065,13 +1066,13 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi * * @return true if the list of files can be copied to destination. */ boolean canCopy(List<DocumentInfo> files, DocumentInfo dest) { BaseActivity activity = (BaseActivity) getActivity(); final RootInfo root = activity.getCurrentRoot(); private boolean canCopy(List<DocumentInfo> files, RootInfo root, DocumentInfo dest) { if (dest == null || !dest.isDirectory() || !dest.isCreateSupported()) { return false; } // Can't copy folders to Downloads. if (root.isDownloads()) { // Can't copy folders to roots that don't support children. if (!root.supportsChildren()) { for (DocumentInfo docs : files) { if (docs.isDirectory()) { return false; Loading @@ -1079,7 +1080,7 @@ public class DirectoryFragment extends Fragment implements DocumentsAdapter.Envi } } return dest != null && dest.isDirectory() && dest.isCreateSupported(); return true; } public void selectAllFiles() { Loading