Loading src/com/android/documentsui/BaseActivity.java +41 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.concurrent.Executor; Loading @@ -32,6 +33,10 @@ import libcore.io.IoUtils; import android.app.Activity; import android.app.Fragment; 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.net.Uri; import android.os.AsyncTask; Loading Loading @@ -232,9 +237,38 @@ abstract class BaseActivity extends Activity { 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() { String callingPackage = 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); return (extra != null) ? extra : getCallingPackage(); if (extra != null) { callingPackage = extra; } } } finally { return callingPackage; } } public static BaseActivity get(Fragment fragment) { Loading Loading @@ -287,6 +321,9 @@ abstract class BaseActivity extends Activity { /** Currently copying file */ 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_CREATE = 2; public static final int ACTION_GET_CONTENT = 3; Loading Loading @@ -327,6 +364,7 @@ abstract class BaseActivity extends Activity { out.writeString(currentSearch); out.writeMap(dirState); out.writeList(selectedDocumentsForCopy); out.writeList(excludedAuthorities); } public static final Creator<State> CREATOR = new Creator<State>() { Loading @@ -348,6 +386,7 @@ abstract class BaseActivity extends Activity { state.currentSearch = in.readString(); in.readMap(state.dirState, null); in.readList(state.selectedDocumentsForCopy, null); in.readList(state.excludedAuthorities, null); return state; } Loading src/com/android/documentsui/DocumentsActivity.java +2 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,8 @@ public class DocumentsActivity extends BaseActivity { BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false); } state.excludedAuthorities = getExcludedAuthorities(); return state; } Loading src/com/android/documentsui/RootsCache.java +6 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,12 @@ public class RootsCache { 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); } return matching; Loading src/com/android/documentsui/model/RootInfo.java +0 −2 Original line number Diff line number Diff line Loading @@ -55,7 +55,6 @@ public class RootInfo implements Durable, Parcelable { public String mimeTypes; /** Derived fields that aren't persisted */ public String derivedPackageName; public String[] derivedMimeTypes; public int derivedIcon; Loading @@ -75,7 +74,6 @@ public class RootInfo implements Durable, Parcelable { availableBytes = -1; mimeTypes = null; derivedPackageName = null; derivedMimeTypes = null; derivedIcon = 0; } Loading tests/src/com/android/documentsui/RootsCacheTest.java +25 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,31 @@ public class RootsCacheTest extends AndroidTestCase { 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) { assertEquals(expected.size(), actual.size()); for (Object o : expected) { Loading Loading
src/com/android/documentsui/BaseActivity.java +41 −2 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.concurrent.Executor; Loading @@ -32,6 +33,10 @@ import libcore.io.IoUtils; import android.app.Activity; import android.app.Fragment; 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.net.Uri; import android.os.AsyncTask; Loading Loading @@ -232,9 +237,38 @@ abstract class BaseActivity extends Activity { 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() { String callingPackage = 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); return (extra != null) ? extra : getCallingPackage(); if (extra != null) { callingPackage = extra; } } } finally { return callingPackage; } } public static BaseActivity get(Fragment fragment) { Loading Loading @@ -287,6 +321,9 @@ abstract class BaseActivity extends Activity { /** Currently copying file */ 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_CREATE = 2; public static final int ACTION_GET_CONTENT = 3; Loading Loading @@ -327,6 +364,7 @@ abstract class BaseActivity extends Activity { out.writeString(currentSearch); out.writeMap(dirState); out.writeList(selectedDocumentsForCopy); out.writeList(excludedAuthorities); } public static final Creator<State> CREATOR = new Creator<State>() { Loading @@ -348,6 +386,7 @@ abstract class BaseActivity extends Activity { state.currentSearch = in.readString(); in.readMap(state.dirState, null); in.readList(state.selectedDocumentsForCopy, null); in.readList(state.excludedAuthorities, null); return state; } Loading
src/com/android/documentsui/DocumentsActivity.java +2 −0 Original line number Diff line number Diff line Loading @@ -256,6 +256,8 @@ public class DocumentsActivity extends BaseActivity { BaseActivity.DocumentsIntent.EXTRA_DIRECTORY_COPY, false); } state.excludedAuthorities = getExcludedAuthorities(); return state; } Loading
src/com/android/documentsui/RootsCache.java +6 −0 Original line number Diff line number Diff line Loading @@ -383,6 +383,12 @@ public class RootsCache { 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); } return matching; Loading
src/com/android/documentsui/model/RootInfo.java +0 −2 Original line number Diff line number Diff line Loading @@ -55,7 +55,6 @@ public class RootInfo implements Durable, Parcelable { public String mimeTypes; /** Derived fields that aren't persisted */ public String derivedPackageName; public String[] derivedMimeTypes; public int derivedIcon; Loading @@ -75,7 +74,6 @@ public class RootInfo implements Durable, Parcelable { availableBytes = -1; mimeTypes = null; derivedPackageName = null; derivedMimeTypes = null; derivedIcon = 0; } Loading
tests/src/com/android/documentsui/RootsCacheTest.java +25 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,31 @@ public class RootsCacheTest extends AndroidTestCase { 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) { assertEquals(expected.size(), actual.size()); for (Object o : expected) { Loading