Loading packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +3 −1 Original line number Diff line number Diff line Loading @@ -191,7 +191,9 @@ public class DirectoryFragment extends Fragment { authority, docId, query); return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); case TYPE_RECENT_OPEN: return new RecentLoader(context); final RootsCache roots = DocumentsApplication.getRootsCache(context); final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); return new RecentLoader(context, matchingRoots); default: throw new IllegalStateException("Unknown type " + mType); Loading packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +4 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ public class DocumentsActivity extends Activity { } mState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false); mState.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(this); if (mState.action == ACTION_MANAGE) { mState.sortOrder = SORT_ORDER_LAST_MODIFIED; Loading Loading @@ -701,6 +702,7 @@ public class DocumentsActivity extends Activity { public boolean allowMultiple = false; public boolean showSize = false; public boolean localOnly = false; public boolean showAdvanced = false; /** Current user navigation stack; empty implies recents. */ public DocumentStack stack = new DocumentStack(); Loading Loading @@ -733,6 +735,7 @@ public class DocumentsActivity extends Activity { out.writeInt(allowMultiple ? 1 : 0); out.writeInt(showSize ? 1 : 0); out.writeInt(localOnly ? 1 : 0); out.writeInt(showAdvanced ? 1 : 0); DurableUtils.writeToParcel(out, stack); out.writeString(currentSearch); } Loading @@ -748,6 +751,7 @@ public class DocumentsActivity extends Activity { state.allowMultiple = in.readInt() != 0; state.showSize = in.readInt() != 0; state.localOnly = in.readInt() != 0; state.showAdvanced = in.readInt() != 0; DurableUtils.readFromParcel(in, state.stack); state.currentSearch = in.readString(); return state; Loading packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java +5 −3 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> { return executor; } private final List<RootInfo> mRoots; private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap(); private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED; Loading Loading @@ -133,8 +135,9 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> { } } public RecentLoader(Context context) { public RecentLoader(Context context, List<RootInfo> roots) { super(context); mRoots = roots; } @Override Loading @@ -143,8 +146,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> { // First time through we kick off all the recent tasks, and wait // around to see if everyone finishes quickly. final RootsCache roots = DocumentsApplication.getRootsCache(getContext()); for (RootInfo root : roots.getRoots()) { for (RootInfo root : mRoots) { if ((root.flags & Root.FLAG_SUPPORTS_RECENTS) != 0) { final RecentTask task = new RecentTask(root.authority, root.rootId); mTasks.put(root, task); Loading packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +57 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; import android.util.Log; import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.model.RootInfo; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Objects; Loading @@ -40,6 +41,7 @@ import com.google.android.collect.Lists; import libcore.io.IoUtils; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -75,6 +77,7 @@ public class RootsCache { final RootInfo root = new RootInfo(); root.rootType = Root.ROOT_TYPE_SHORTCUT; root.icon = R.drawable.ic_dir; root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE; root.title = mContext.getString(R.string.root_recent); root.availableBytes = -1; Loading Loading @@ -150,6 +153,60 @@ public class RootsCache { return mRoots; } /** * Flags that declare explicit content types. */ private static final int FLAGS_CONTENT_MASK = Root.FLAG_PROVIDES_IMAGES | Root.FLAG_PROVIDES_AUDIO | Root.FLAG_PROVIDES_VIDEO; @GuardedBy("ActivityThread") public List<RootInfo> getMatchingRoots(State state) { // Determine acceptable content flags int includeFlags = 0; for (String acceptMime : state.acceptMimes) { final String[] type = acceptMime.split("/"); if (type.length != 2) continue; if ("image".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_IMAGES; } else if ("audio".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_AUDIO; } else if ("video".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_VIDEO; } else if ("*".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_IMAGES | Root.FLAG_PROVIDES_AUDIO | Root.FLAG_PROVIDES_VIDEO; } } ArrayList<RootInfo> matching = Lists.newArrayList(); for (RootInfo root : mRoots) { final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0; final boolean advanced = (root.flags & Root.FLAG_ADVANCED) != 0; final boolean localOnly = (root.flags & Root.FLAG_LOCAL_ONLY) != 0; // Exclude read-only devices when creating if (state.action == State.ACTION_CREATE && !supportsCreate) continue; // Exclude advanced devices when not requested if (!state.showAdvanced && advanced) continue; // Exclude non-local devices when local only if (state.localOnly && !localOnly) continue; if ((root.flags & FLAGS_CONTENT_MASK) != 0) { // This root offers specific content, so only include if the // caller asked for that content type. if ((root.flags & includeFlags) == 0) { // Sorry, no overlap. continue; } } matching.add(root); } return matching; } @GuardedBy("ActivityThread") public static Drawable resolveDocumentIcon(Context context, String mimeType) { if (Document.MIME_TYPE_DIR.equals(mimeType)) { Loading packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java +22 −24 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.documentsui; import static com.android.documentsui.DocumentsActivity.TAG; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; Loading @@ -28,7 +26,6 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.provider.DocumentsContract.Root; import android.text.format.Formatter; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -39,6 +36,7 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.SectionedListAdapter.SectionAdapter; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; Loading Loading @@ -76,24 +74,31 @@ public class RootsFragment extends Fragment { public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final Context context = inflater.getContext(); final RootsCache roots = DocumentsApplication.getRootsCache(context); final View view = inflater.inflate(R.layout.fragment_roots, container, false); mList = (ListView) view.findViewById(android.R.id.list); mList.setOnItemClickListener(mItemListener); final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); mAdapter = new SectionedRootsAdapter(context, roots.getRoots(), includeApps); return view; } @Override public void onStart() { super.onStart(); updateRootsAdapter(); } private void updateRootsAdapter() { final Context context = getActivity(); mAdapter.updateVisible(SettingsActivity.getDisplayAdvancedDevices(context)); final State state = ((DocumentsActivity) context).getDisplayState(); state.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(context); final RootsCache roots = DocumentsApplication.getRootsCache(context); final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); mAdapter = new SectionedRootsAdapter(context, matchingRoots, includeApps); mList.setAdapter(mAdapter); } Loading Loading @@ -211,18 +216,15 @@ public class RootsFragment extends Fragment { private final RootsAdapter mServices; private final RootsAdapter mShortcuts; private final RootsAdapter mDevices; private final RootsAdapter mDevicesAdvanced; private final AppsAdapter mApps; public SectionedRootsAdapter(Context context, List<RootInfo> roots, Intent includeApps) { mServices = new RootsAdapter(context, R.string.root_type_service); mShortcuts = new RootsAdapter(context, R.string.root_type_shortcut); mDevices = new RootsAdapter(context, R.string.root_type_device); mDevicesAdvanced = new RootsAdapter(context, R.string.root_type_device); mApps = new AppsAdapter(context); for (RootInfo root : roots) { Log.d(TAG, "Found rootType=" + root.rootType); switch (root.rootType) { case Root.ROOT_TYPE_SERVICE: mServices.add(root); Loading @@ -231,10 +233,7 @@ public class RootsFragment extends Fragment { mShortcuts.add(root); break; case Root.ROOT_TYPE_DEVICE: mDevicesAdvanced.add(root); if ((root.flags & Root.FLAG_ADVANCED) == 0) { mDevices.add(root); } break; } } Loading @@ -256,23 +255,16 @@ public class RootsFragment extends Fragment { mServices.sort(comp); mShortcuts.sort(comp); mDevices.sort(comp); mDevicesAdvanced.sort(comp); } public void updateVisible(boolean showAdvanced) { clearSections(); if (mServices.getCount() > 0) { addSection(mServices); } if (mShortcuts.getCount() > 0) { addSection(mShortcuts); } final RootsAdapter devices = showAdvanced ? mDevicesAdvanced : mDevices; if (devices.getCount() > 0) { addSection(devices); if (mDevices.getCount() > 0) { addSection(mDevices); } if (mApps.getCount() > 0) { addSection(mApps); } Loading @@ -282,6 +274,12 @@ public class RootsFragment extends Fragment { public static class RootComparator implements Comparator<RootInfo> { @Override public int compare(RootInfo lhs, RootInfo rhs) { if (lhs.authority == null) { return -1; } else if (rhs.authority == null) { return 1; } final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title); if (score != 0) { return score; Loading Loading
packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +3 −1 Original line number Diff line number Diff line Loading @@ -191,7 +191,9 @@ public class DirectoryFragment extends Fragment { authority, docId, query); return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); case TYPE_RECENT_OPEN: return new RecentLoader(context); final RootsCache roots = DocumentsApplication.getRootsCache(context); final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); return new RecentLoader(context, matchingRoots); default: throw new IllegalStateException("Unknown type " + mType); Loading
packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +4 −0 Original line number Diff line number Diff line Loading @@ -161,6 +161,7 @@ public class DocumentsActivity extends Activity { } mState.localOnly = intent.getBooleanExtra(Intent.EXTRA_LOCAL_ONLY, false); mState.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(this); if (mState.action == ACTION_MANAGE) { mState.sortOrder = SORT_ORDER_LAST_MODIFIED; Loading Loading @@ -701,6 +702,7 @@ public class DocumentsActivity extends Activity { public boolean allowMultiple = false; public boolean showSize = false; public boolean localOnly = false; public boolean showAdvanced = false; /** Current user navigation stack; empty implies recents. */ public DocumentStack stack = new DocumentStack(); Loading Loading @@ -733,6 +735,7 @@ public class DocumentsActivity extends Activity { out.writeInt(allowMultiple ? 1 : 0); out.writeInt(showSize ? 1 : 0); out.writeInt(localOnly ? 1 : 0); out.writeInt(showAdvanced ? 1 : 0); DurableUtils.writeToParcel(out, stack); out.writeString(currentSearch); } Loading @@ -748,6 +751,7 @@ public class DocumentsActivity extends Activity { state.allowMultiple = in.readInt() != 0; state.showSize = in.readInt() != 0; state.localOnly = in.readInt() != 0; state.showAdvanced = in.readInt() != 0; DurableUtils.readFromParcel(in, state.stack); state.currentSearch = in.readString(); return state; Loading
packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java +5 −3 Original line number Diff line number Diff line Loading @@ -78,6 +78,8 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> { return executor; } private final List<RootInfo> mRoots; private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap(); private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED; Loading Loading @@ -133,8 +135,9 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> { } } public RecentLoader(Context context) { public RecentLoader(Context context, List<RootInfo> roots) { super(context); mRoots = roots; } @Override Loading @@ -143,8 +146,7 @@ public class RecentLoader extends AsyncTaskLoader<DirectoryResult> { // First time through we kick off all the recent tasks, and wait // around to see if everyone finishes quickly. final RootsCache roots = DocumentsApplication.getRootsCache(getContext()); for (RootInfo root : roots.getRoots()) { for (RootInfo root : mRoots) { if ((root.flags & Root.FLAG_SUPPORTS_RECENTS) != 0) { final RecentTask task = new RecentTask(root.authority, root.rootId); mTasks.put(root, task); Loading
packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +57 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; import android.util.Log; import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.model.RootInfo; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.Objects; Loading @@ -40,6 +41,7 @@ import com.google.android.collect.Lists; import libcore.io.IoUtils; import java.util.ArrayList; import java.util.List; /** Loading Loading @@ -75,6 +77,7 @@ public class RootsCache { final RootInfo root = new RootInfo(); root.rootType = Root.ROOT_TYPE_SHORTCUT; root.icon = R.drawable.ic_dir; root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE; root.title = mContext.getString(R.string.root_recent); root.availableBytes = -1; Loading Loading @@ -150,6 +153,60 @@ public class RootsCache { return mRoots; } /** * Flags that declare explicit content types. */ private static final int FLAGS_CONTENT_MASK = Root.FLAG_PROVIDES_IMAGES | Root.FLAG_PROVIDES_AUDIO | Root.FLAG_PROVIDES_VIDEO; @GuardedBy("ActivityThread") public List<RootInfo> getMatchingRoots(State state) { // Determine acceptable content flags int includeFlags = 0; for (String acceptMime : state.acceptMimes) { final String[] type = acceptMime.split("/"); if (type.length != 2) continue; if ("image".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_IMAGES; } else if ("audio".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_AUDIO; } else if ("video".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_VIDEO; } else if ("*".equals(type[0])) { includeFlags |= Root.FLAG_PROVIDES_IMAGES | Root.FLAG_PROVIDES_AUDIO | Root.FLAG_PROVIDES_VIDEO; } } ArrayList<RootInfo> matching = Lists.newArrayList(); for (RootInfo root : mRoots) { final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0; final boolean advanced = (root.flags & Root.FLAG_ADVANCED) != 0; final boolean localOnly = (root.flags & Root.FLAG_LOCAL_ONLY) != 0; // Exclude read-only devices when creating if (state.action == State.ACTION_CREATE && !supportsCreate) continue; // Exclude advanced devices when not requested if (!state.showAdvanced && advanced) continue; // Exclude non-local devices when local only if (state.localOnly && !localOnly) continue; if ((root.flags & FLAGS_CONTENT_MASK) != 0) { // This root offers specific content, so only include if the // caller asked for that content type. if ((root.flags & includeFlags) == 0) { // Sorry, no overlap. continue; } } matching.add(root); } return matching; } @GuardedBy("ActivityThread") public static Drawable resolveDocumentIcon(Context context, String mimeType) { if (Document.MIME_TYPE_DIR.equals(mimeType)) { Loading
packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java +22 −24 Original line number Diff line number Diff line Loading @@ -16,8 +16,6 @@ package com.android.documentsui; import static com.android.documentsui.DocumentsActivity.TAG; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; Loading @@ -28,7 +26,6 @@ import android.content.pm.ResolveInfo; import android.os.Bundle; import android.provider.DocumentsContract.Root; import android.text.format.Formatter; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; Loading @@ -39,6 +36,7 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import com.android.documentsui.DocumentsActivity.State; import com.android.documentsui.SectionedListAdapter.SectionAdapter; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; Loading Loading @@ -76,24 +74,31 @@ public class RootsFragment extends Fragment { public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final Context context = inflater.getContext(); final RootsCache roots = DocumentsApplication.getRootsCache(context); final View view = inflater.inflate(R.layout.fragment_roots, container, false); mList = (ListView) view.findViewById(android.R.id.list); mList.setOnItemClickListener(mItemListener); final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); mAdapter = new SectionedRootsAdapter(context, roots.getRoots(), includeApps); return view; } @Override public void onStart() { super.onStart(); updateRootsAdapter(); } private void updateRootsAdapter() { final Context context = getActivity(); mAdapter.updateVisible(SettingsActivity.getDisplayAdvancedDevices(context)); final State state = ((DocumentsActivity) context).getDisplayState(); state.showAdvanced = SettingsActivity.getDisplayAdvancedDevices(context); final RootsCache roots = DocumentsApplication.getRootsCache(context); final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); final Intent includeApps = getArguments().getParcelable(EXTRA_INCLUDE_APPS); mAdapter = new SectionedRootsAdapter(context, matchingRoots, includeApps); mList.setAdapter(mAdapter); } Loading Loading @@ -211,18 +216,15 @@ public class RootsFragment extends Fragment { private final RootsAdapter mServices; private final RootsAdapter mShortcuts; private final RootsAdapter mDevices; private final RootsAdapter mDevicesAdvanced; private final AppsAdapter mApps; public SectionedRootsAdapter(Context context, List<RootInfo> roots, Intent includeApps) { mServices = new RootsAdapter(context, R.string.root_type_service); mShortcuts = new RootsAdapter(context, R.string.root_type_shortcut); mDevices = new RootsAdapter(context, R.string.root_type_device); mDevicesAdvanced = new RootsAdapter(context, R.string.root_type_device); mApps = new AppsAdapter(context); for (RootInfo root : roots) { Log.d(TAG, "Found rootType=" + root.rootType); switch (root.rootType) { case Root.ROOT_TYPE_SERVICE: mServices.add(root); Loading @@ -231,10 +233,7 @@ public class RootsFragment extends Fragment { mShortcuts.add(root); break; case Root.ROOT_TYPE_DEVICE: mDevicesAdvanced.add(root); if ((root.flags & Root.FLAG_ADVANCED) == 0) { mDevices.add(root); } break; } } Loading @@ -256,23 +255,16 @@ public class RootsFragment extends Fragment { mServices.sort(comp); mShortcuts.sort(comp); mDevices.sort(comp); mDevicesAdvanced.sort(comp); } public void updateVisible(boolean showAdvanced) { clearSections(); if (mServices.getCount() > 0) { addSection(mServices); } if (mShortcuts.getCount() > 0) { addSection(mShortcuts); } final RootsAdapter devices = showAdvanced ? mDevicesAdvanced : mDevices; if (devices.getCount() > 0) { addSection(devices); if (mDevices.getCount() > 0) { addSection(mDevices); } if (mApps.getCount() > 0) { addSection(mApps); } Loading @@ -282,6 +274,12 @@ public class RootsFragment extends Fragment { public static class RootComparator implements Comparator<RootInfo> { @Override public int compare(RootInfo lhs, RootInfo rhs) { if (lhs.authority == null) { return -1; } else if (rhs.authority == null) { return 1; } final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title); if (score != 0) { return score; Loading