am e04b20dd: am c783a5e7: Merge "Enable apps to exclude their own roots from the DocumentsUI roots list." into mnc-dev
* commit 'e04b20dd763a212596a3a77ca342fe4fb33e2939': Enable apps to exclude their own roots from the DocumentsUI roots list.
This commit is contained in:
@@ -26099,6 +26099,7 @@ package android.provider {
|
|||||||
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
|
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
|
||||||
method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
|
method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
|
||||||
field public static final java.lang.String EXTRA_ERROR = "error";
|
field public static final java.lang.String EXTRA_ERROR = "error";
|
||||||
|
field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
|
||||||
field public static final java.lang.String EXTRA_INFO = "info";
|
field public static final java.lang.String EXTRA_INFO = "info";
|
||||||
field public static final java.lang.String EXTRA_LOADING = "loading";
|
field public static final java.lang.String EXTRA_LOADING = "loading";
|
||||||
field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
|
field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
|
||||||
|
|||||||
@@ -28029,6 +28029,7 @@ package android.provider {
|
|||||||
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
|
method public static boolean isDocumentUri(android.content.Context, android.net.Uri);
|
||||||
method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
|
method public static android.net.Uri renameDocument(android.content.ContentResolver, android.net.Uri, java.lang.String);
|
||||||
field public static final java.lang.String EXTRA_ERROR = "error";
|
field public static final java.lang.String EXTRA_ERROR = "error";
|
||||||
|
field public static final java.lang.String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
|
||||||
field public static final java.lang.String EXTRA_INFO = "info";
|
field public static final java.lang.String EXTRA_INFO = "info";
|
||||||
field public static final java.lang.String EXTRA_LOADING = "loading";
|
field public static final java.lang.String EXTRA_LOADING = "loading";
|
||||||
field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
|
field public static final java.lang.String PROVIDER_INTERFACE = "android.content.action.DOCUMENTS_PROVIDER";
|
||||||
|
|||||||
@@ -92,6 +92,12 @@ public final class DocumentsContract {
|
|||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
public static final String EXTRA_SHOW_ADVANCED = "android.content.extra.SHOW_ADVANCED";
|
public static final String EXTRA_SHOW_ADVANCED = "android.content.extra.SHOW_ADVANCED";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this in a DocumentsUI intent to cause a package's own roots to be
|
||||||
|
* excluded from the roots list.
|
||||||
|
*/
|
||||||
|
public static final String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Included in {@link AssetFileDescriptor#getExtras()} when returned
|
* Included in {@link AssetFileDescriptor#getExtras()} when returned
|
||||||
* thumbnail should be rotated.
|
* thumbnail should be rotated.
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@@ -32,6 +33,10 @@ import libcore.io.IoUtils;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ProviderInfo;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
@@ -232,9 +237,38 @@ abstract class BaseActivity extends Activity {
|
|||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final List<String> getExcludedAuthorities() {
|
||||||
|
List<String> authorities = new ArrayList<>();
|
||||||
|
if (getIntent().getBooleanExtra(DocumentsContract.EXTRA_EXCLUDE_SELF, false)) {
|
||||||
|
// Exclude roots provided by the calling package.
|
||||||
|
String packageName = getCallingPackageMaybeExtra();
|
||||||
|
try {
|
||||||
|
PackageInfo pkgInfo = getPackageManager().getPackageInfo(packageName,
|
||||||
|
PackageManager.GET_PROVIDERS);
|
||||||
|
for (ProviderInfo provider: pkgInfo.providers) {
|
||||||
|
authorities.add(provider.authority);
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
Log.e(mTag, "Calling package name does not resolve: " + packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return authorities;
|
||||||
|
}
|
||||||
|
|
||||||
final String getCallingPackageMaybeExtra() {
|
final String getCallingPackageMaybeExtra() {
|
||||||
final String extra = getIntent().getStringExtra(DocumentsContract.EXTRA_PACKAGE_NAME);
|
String callingPackage = getCallingPackage();
|
||||||
return (extra != null) ? extra : getCallingPackage();
|
// System apps can set the calling package name using an extra.
|
||||||
|
try {
|
||||||
|
ApplicationInfo info = getPackageManager().getApplicationInfo(callingPackage, 0);
|
||||||
|
if (info.isSystemApp() || info.isUpdatedSystemApp()) {
|
||||||
|
final String extra = getIntent().getStringExtra(DocumentsContract.EXTRA_PACKAGE_NAME);
|
||||||
|
if (extra != null) {
|
||||||
|
callingPackage = extra;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
return callingPackage;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaseActivity get(Fragment fragment) {
|
public static BaseActivity get(Fragment fragment) {
|
||||||
@@ -287,6 +321,9 @@ abstract class BaseActivity extends Activity {
|
|||||||
/** Currently copying file */
|
/** Currently copying file */
|
||||||
public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>();
|
public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>();
|
||||||
|
|
||||||
|
/** Name of the package that started DocsUI */
|
||||||
|
public List<String> excludedAuthorities = new ArrayList<>();
|
||||||
|
|
||||||
public static final int ACTION_OPEN = 1;
|
public static final int ACTION_OPEN = 1;
|
||||||
public static final int ACTION_CREATE = 2;
|
public static final int ACTION_CREATE = 2;
|
||||||
public static final int ACTION_GET_CONTENT = 3;
|
public static final int ACTION_GET_CONTENT = 3;
|
||||||
@@ -327,6 +364,7 @@ abstract class BaseActivity extends Activity {
|
|||||||
out.writeString(currentSearch);
|
out.writeString(currentSearch);
|
||||||
out.writeMap(dirState);
|
out.writeMap(dirState);
|
||||||
out.writeList(selectedDocumentsForCopy);
|
out.writeList(selectedDocumentsForCopy);
|
||||||
|
out.writeList(excludedAuthorities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Creator<State> CREATOR = new Creator<State>() {
|
public static final Creator<State> CREATOR = new Creator<State>() {
|
||||||
@@ -348,6 +386,7 @@ abstract class BaseActivity extends Activity {
|
|||||||
state.currentSearch = in.readString();
|
state.currentSearch = in.readString();
|
||||||
in.readMap(state.dirState, null);
|
in.readMap(state.dirState, null);
|
||||||
in.readList(state.selectedDocumentsForCopy, null);
|
in.readList(state.selectedDocumentsForCopy, null);
|
||||||
|
in.readList(state.excludedAuthorities, null);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -256,6 +256,8 @@ public class DocumentsActivity extends BaseActivity {
|
|||||||
BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false);
|
BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.excludedAuthorities = getExcludedAuthorities();
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -383,6 +383,12 @@ public class RootsCache {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exclude roots from the calling package.
|
||||||
|
if (state.excludedAuthorities.contains(root.authority)) {
|
||||||
|
if (LOGD) Log.d(TAG, "Excluding root " + root.authority + " from calling package.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
matching.add(root);
|
matching.add(root);
|
||||||
}
|
}
|
||||||
return matching;
|
return matching;
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ public class RootInfo implements Durable, Parcelable {
|
|||||||
public String mimeTypes;
|
public String mimeTypes;
|
||||||
|
|
||||||
/** Derived fields that aren't persisted */
|
/** Derived fields that aren't persisted */
|
||||||
public String derivedPackageName;
|
|
||||||
public String[] derivedMimeTypes;
|
public String[] derivedMimeTypes;
|
||||||
public int derivedIcon;
|
public int derivedIcon;
|
||||||
|
|
||||||
@@ -75,7 +74,6 @@ public class RootInfo implements Durable, Parcelable {
|
|||||||
availableBytes = -1;
|
availableBytes = -1;
|
||||||
mimeTypes = null;
|
mimeTypes = null;
|
||||||
|
|
||||||
derivedPackageName = null;
|
|
||||||
derivedMimeTypes = null;
|
derivedMimeTypes = null;
|
||||||
derivedIcon = 0;
|
derivedIcon = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,31 @@ public class RootsCacheTest extends AndroidTestCase {
|
|||||||
RootsCache.getMatchingRoots(mRoots, mState));
|
RootsCache.getMatchingRoots(mRoots, mState));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testExcludedAuthorities() throws Exception {
|
||||||
|
final List<RootInfo> roots = Lists.newArrayList();
|
||||||
|
|
||||||
|
// Set up some roots
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
RootInfo root = new RootInfo();
|
||||||
|
root.authority = "authority" + i;
|
||||||
|
roots.add(root);
|
||||||
|
}
|
||||||
|
// Make some allowed authorities
|
||||||
|
List<RootInfo> allowedRoots = Lists.newArrayList(
|
||||||
|
roots.get(0), roots.get(2), roots.get(4));
|
||||||
|
// Set up the excluded authority list
|
||||||
|
for (RootInfo root: roots) {
|
||||||
|
if (!allowedRoots.contains(root)) {
|
||||||
|
mState.excludedAuthorities.add(root.authority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mState.acceptMimes = new String[] { "*/*" };
|
||||||
|
|
||||||
|
assertContainsExactly(
|
||||||
|
allowedRoots,
|
||||||
|
RootsCache.getMatchingRoots(roots, mState));
|
||||||
|
}
|
||||||
|
|
||||||
private static void assertContainsExactly(List<?> expected, List<?> actual) {
|
private static void assertContainsExactly(List<?> expected, List<?> actual) {
|
||||||
assertEquals(expected.size(), actual.size());
|
assertEquals(expected.size(), actual.size());
|
||||||
for (Object o : expected) {
|
for (Object o : expected) {
|
||||||
|
|||||||
Reference in New Issue
Block a user