Loading packages/DocumentsUI/AndroidManifest.xml +13 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,19 @@ <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.document/root" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/zip" android:host="com.android.providers.downloads.documents" android:scheme="content" /> <data android:mimeType="application/x-zip" android:host="com.android.providers.downloads.documents" android:scheme="content" /> <data android:mimeType="application/x-zip-compressed" android:host="com.android.providers.downloads.documents" android:scheme="content" /> </intent-filter> </activity> <activity Loading packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -541,7 +541,7 @@ public abstract class BaseActivity extends Activity implements SearchManagerList } } private DocumentInfo getRootDocumentBlocking(RootInfo root) { DocumentInfo getRootDocumentBlocking(RootInfo root) { try { final Uri uri = DocumentsContract.buildDocumentUri( root.authority, root.documentId); Loading packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java +17 −21 Original line number Diff line number Diff line Loading @@ -182,10 +182,7 @@ public class DownloadsActivity extends BaseActivity { @Override public void onDocumentPicked(DocumentInfo doc, SiblingProvider siblings) { final FragmentManager fm = getFragmentManager(); if (doc.isContainer()) { openContainerDocument(doc); } else { Preconditions.checkArgument(!doc.isDirectory()); // First try managing the document; we expect manager to filter // based on authority, so we don't grant. final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT); Loading @@ -194,7 +191,7 @@ public class DownloadsActivity extends BaseActivity { try { startActivity(manage); } catch (ActivityNotFoundException ex) { // Fall back to viewing // Fall back to viewing. final Intent view = new Intent(Intent.ACTION_VIEW); view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); view.setData(doc.derivedUri); Loading @@ -207,7 +204,6 @@ public class DownloadsActivity extends BaseActivity { } } } } @Override public void onDocumentsPicked(List<DocumentInfo> docs) {} Loading packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java +47 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Parcelable; import android.provider.DocumentsContract; Loading @@ -53,8 +54,10 @@ import com.android.documentsui.model.DurableUtils; import com.android.documentsui.model.RootInfo; import com.android.documentsui.services.FileOperationService; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; /** Loading Loading @@ -111,6 +114,10 @@ public class FilesActivity extends BaseActivity { checkState(uri == null || uri.getAuthority() == null || LauncherActivity.isLaunchUri(uri)); refreshCurrentRootAndDirectory(ANIM_NONE); } else if (intent.getAction() == Intent.ACTION_VIEW) { checkArgument(uri != null); new OpenUriForViewTask().executeOnExecutor( ProviderExecutor.forAuthority(uri.getAuthority()), uri); } else if (DocumentsContract.isRootUri(this, uri)) { if (DEBUG) Log.d(TAG, "Launching with root URI."); // If we've got a specific root to display, restore that root using a dedicated Loading Loading @@ -449,4 +456,44 @@ public class FilesActivity extends BaseActivity { setResult(Activity.RESULT_OK, intent); finish(); } /** * Builds a stack for the specific Uris. Multi roots are not supported, as it's impossible * to know which root to select. Also, the stack doesn't contain intermediate directories. * It's primarly used for opening ZIP archives from Downloads app. */ final class OpenUriForViewTask extends AsyncTask<Uri, Void, Void> { @Override protected Void doInBackground(Uri... params) { final Uri uri = params[0]; final RootsCache rootsCache = DocumentsApplication.getRootsCache(FilesActivity.this); final String authority = uri.getAuthority(); final Collection<RootInfo> roots = rootsCache.getRootsForAuthorityBlocking(authority); if (roots.isEmpty()) { Log.e(TAG, "Failed to find root for the requested Uri: " + uri); return null; } final RootInfo root = roots.iterator().next(); mState.stack.root = root; try { mState.stack.add(DocumentInfo.fromUri(getContentResolver(), uri)); } catch (FileNotFoundException e) { Log.e(TAG, "Failed to resolve DocumentInfo from Uri: " + uri); } mState.stack.add(getRootDocumentBlocking(root)); return null; } @Override protected void onPostExecute(Void result) { if (isDestroyed()) { return; } refreshCurrentRootAndDirectory(ANIM_NONE); } } } packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +29 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import libcore.io.IoUtils; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; Loading Loading @@ -159,6 +160,21 @@ public class RootsCache { } } /** * Load roots from a stopped authority. Normal {@link UpdateTask} passes * ignore stopped applications. */ private void loadStoppedAuthority(String authority) { final ContentResolver resolver = mContext.getContentResolver(); synchronized (mLock) { if (DEBUG) { Log.d(TAG, "Loading stopped authority " + authority); } mRoots.putAll(authority, loadRootsForAuthority(resolver, authority)); mStoppedAuthorities.remove(authority); } } private class UpdateTask extends AsyncTask<Void, Void, Void> { private final String mFilterPackage; Loading Loading @@ -360,6 +376,19 @@ public class RootsCache { } } /** * Returns a list of roots for the specified authority. If not found, then * an empty list is returned. */ public Collection<RootInfo> getRootsForAuthorityBlocking(String authority) { waitForFirstLoad(); loadStoppedAuthority(authority); synchronized (mLock) { final Collection<RootInfo> roots = mRoots.get(authority); return roots != null ? roots : Collections.<RootInfo>emptyList(); } } public void setOnCacheUpdateListener(OnCacheUpdateListener cacheUpdateListener) { mCacheUpdateListener = cacheUpdateListener; } Loading Loading
packages/DocumentsUI/AndroidManifest.xml +13 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,19 @@ <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.document/root" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="application/zip" android:host="com.android.providers.downloads.documents" android:scheme="content" /> <data android:mimeType="application/x-zip" android:host="com.android.providers.downloads.documents" android:scheme="content" /> <data android:mimeType="application/x-zip-compressed" android:host="com.android.providers.downloads.documents" android:scheme="content" /> </intent-filter> </activity> <activity Loading
packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +1 −1 Original line number Diff line number Diff line Loading @@ -541,7 +541,7 @@ public abstract class BaseActivity extends Activity implements SearchManagerList } } private DocumentInfo getRootDocumentBlocking(RootInfo root) { DocumentInfo getRootDocumentBlocking(RootInfo root) { try { final Uri uri = DocumentsContract.buildDocumentUri( root.authority, root.documentId); Loading
packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java +17 −21 Original line number Diff line number Diff line Loading @@ -182,10 +182,7 @@ public class DownloadsActivity extends BaseActivity { @Override public void onDocumentPicked(DocumentInfo doc, SiblingProvider siblings) { final FragmentManager fm = getFragmentManager(); if (doc.isContainer()) { openContainerDocument(doc); } else { Preconditions.checkArgument(!doc.isDirectory()); // First try managing the document; we expect manager to filter // based on authority, so we don't grant. final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT); Loading @@ -194,7 +191,7 @@ public class DownloadsActivity extends BaseActivity { try { startActivity(manage); } catch (ActivityNotFoundException ex) { // Fall back to viewing // Fall back to viewing. final Intent view = new Intent(Intent.ACTION_VIEW); view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); view.setData(doc.derivedUri); Loading @@ -207,7 +204,6 @@ public class DownloadsActivity extends BaseActivity { } } } } @Override public void onDocumentsPicked(List<DocumentInfo> docs) {} Loading
packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java +47 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Parcelable; import android.provider.DocumentsContract; Loading @@ -53,8 +54,10 @@ import com.android.documentsui.model.DurableUtils; import com.android.documentsui.model.RootInfo; import com.android.documentsui.services.FileOperationService; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; /** Loading Loading @@ -111,6 +114,10 @@ public class FilesActivity extends BaseActivity { checkState(uri == null || uri.getAuthority() == null || LauncherActivity.isLaunchUri(uri)); refreshCurrentRootAndDirectory(ANIM_NONE); } else if (intent.getAction() == Intent.ACTION_VIEW) { checkArgument(uri != null); new OpenUriForViewTask().executeOnExecutor( ProviderExecutor.forAuthority(uri.getAuthority()), uri); } else if (DocumentsContract.isRootUri(this, uri)) { if (DEBUG) Log.d(TAG, "Launching with root URI."); // If we've got a specific root to display, restore that root using a dedicated Loading Loading @@ -449,4 +456,44 @@ public class FilesActivity extends BaseActivity { setResult(Activity.RESULT_OK, intent); finish(); } /** * Builds a stack for the specific Uris. Multi roots are not supported, as it's impossible * to know which root to select. Also, the stack doesn't contain intermediate directories. * It's primarly used for opening ZIP archives from Downloads app. */ final class OpenUriForViewTask extends AsyncTask<Uri, Void, Void> { @Override protected Void doInBackground(Uri... params) { final Uri uri = params[0]; final RootsCache rootsCache = DocumentsApplication.getRootsCache(FilesActivity.this); final String authority = uri.getAuthority(); final Collection<RootInfo> roots = rootsCache.getRootsForAuthorityBlocking(authority); if (roots.isEmpty()) { Log.e(TAG, "Failed to find root for the requested Uri: " + uri); return null; } final RootInfo root = roots.iterator().next(); mState.stack.root = root; try { mState.stack.add(DocumentInfo.fromUri(getContentResolver(), uri)); } catch (FileNotFoundException e) { Log.e(TAG, "Failed to resolve DocumentInfo from Uri: " + uri); } mState.stack.add(getRootDocumentBlocking(root)); return null; } @Override protected void onPostExecute(Void result) { if (isDestroyed()) { return; } refreshCurrentRootAndDirectory(ANIM_NONE); } } }
packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +29 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import libcore.io.IoUtils; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; Loading Loading @@ -159,6 +160,21 @@ public class RootsCache { } } /** * Load roots from a stopped authority. Normal {@link UpdateTask} passes * ignore stopped applications. */ private void loadStoppedAuthority(String authority) { final ContentResolver resolver = mContext.getContentResolver(); synchronized (mLock) { if (DEBUG) { Log.d(TAG, "Loading stopped authority " + authority); } mRoots.putAll(authority, loadRootsForAuthority(resolver, authority)); mStoppedAuthorities.remove(authority); } } private class UpdateTask extends AsyncTask<Void, Void, Void> { private final String mFilterPackage; Loading Loading @@ -360,6 +376,19 @@ public class RootsCache { } } /** * Returns a list of roots for the specified authority. If not found, then * an empty list is returned. */ public Collection<RootInfo> getRootsForAuthorityBlocking(String authority) { waitForFirstLoad(); loadStoppedAuthority(authority); synchronized (mLock) { final Collection<RootInfo> roots = mRoots.get(authority); return roots != null ? roots : Collections.<RootInfo>emptyList(); } } public void setOnCacheUpdateListener(OnCacheUpdateListener cacheUpdateListener) { mCacheUpdateListener = cacheUpdateListener; } Loading