am cfd19c81: am 584004fe: Merge "Tests for persistable Uri permission grants." into klp-dev
* commit 'cfd19c8174f02f50be02cd5f1e2e954a002d6a90':
Tests for persistable Uri permission grants.
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/GrantUriPermission.java b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/GrantUriPermission.java
index 31a3f47..46e1dff 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/GrantUriPermission.java
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/GrantUriPermission.java
@@ -19,27 +19,82 @@
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.UriPermission;
+import android.net.Uri;
import android.util.Log;
+import java.util.List;
+
public class GrantUriPermission extends BroadcastReceiver {
+ public static final String ACTION_GRANT_URI = "grantUri";
+ public static final String ACTION_REVOKE_URI = "revokeUri";
+ public static final String ACTION_START_ACTIVITY = "startActivity";
+ public static final String ACTION_START_SERVICE = "startService";
+ public static final String ACTION_VERIFY_OUTGOING_PERSISTED = "verifyOutgoingPersisted";
+
+ public static final String EXTRA_PACKAGE_NAME = "packageName";
+ public static final String EXTRA_INTENT = Intent.EXTRA_INTENT;
+ public static final String EXTRA_URI = "uri";
+ public static final String EXTRA_MODE = "mode";
+
+ public static final int SUCCESS = 101;
+ public static final int FAILURE = 100;
+
@Override
public void onReceive(Context context, Intent intent) {
- Intent newIntent = (Intent)intent.getParcelableExtra("intent");
- boolean service = intent.getBooleanExtra("service", false);
try {
- if (!service) {
+ final String action = intent.getAction();
+ if (ACTION_GRANT_URI.equals(action)) {
+ final Uri uri = intent.getParcelableExtra(EXTRA_URI);
+ context.grantUriPermission(intent.getStringExtra(EXTRA_PACKAGE_NAME), uri,
+ intent.getIntExtra(EXTRA_MODE, 0));
+
+ } else if (ACTION_REVOKE_URI.equals(action)) {
+ final Uri uri = intent.getParcelableExtra(EXTRA_URI);
+ context.revokeUriPermission(uri, intent.getIntExtra(EXTRA_MODE, 0));
+
+ } else if (ACTION_START_ACTIVITY.equals(action)) {
+ final Intent newIntent = intent.getParcelableExtra(EXTRA_INTENT);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
- } else {
+
+ } else if (ACTION_START_SERVICE.equals(action)) {
+ final Intent newIntent = intent.getParcelableExtra(EXTRA_INTENT);
context.startService(newIntent);
+
+ } else if (ACTION_VERIFY_OUTGOING_PERSISTED.equals(action)) {
+ verifyOutgoingPersisted(context, intent);
}
+
if (isOrderedBroadcast()) {
- setResultCode(101);
+ setResultCode(SUCCESS);
}
} catch (SecurityException e) {
Log.i("GrantUriPermission", "Security exception", e);
if (isOrderedBroadcast()) {
- setResultCode(100);
+ setResultCode(FAILURE);
+ }
+ }
+ }
+
+ private void verifyOutgoingPersisted(Context context, Intent intent) {
+ final Uri uri = intent.getParcelableExtra(EXTRA_URI);
+ final List<UriPermission> perms = context.getContentResolver()
+ .getOutgoingPersistedUriPermissions();
+ if (uri != null) {
+ // Should have a single persisted perm
+ if (perms.size() != 1) {
+ throw new SecurityException("Missing grant");
+ }
+ final UriPermission perm = perms.get(0);
+ if (!perm.getUri().equals(uri)) {
+ throw new SecurityException(
+ "Expected " + uri + " but found " + perm.getUri());
+ }
+ } else {
+ // Should have zero persisted perms
+ if (perms.size() != 0) {
+ throw new SecurityException("Unexpected grant");
}
}
}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
index acf9f6f..d836042 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
@@ -18,7 +18,8 @@
LOCAL_MODULE_TAGS := tests
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+ ../PermissionDeclareApp/src/com/android/cts/permissiondeclareapp/GrantUriPermission.java
LOCAL_SDK_VERSION := current
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
index 8f40cf1..db26eec 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
@@ -23,13 +23,17 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
+import android.content.UriPermission;
import android.database.Cursor;
import android.net.Uri;
import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.util.Log;
+import com.android.cts.permissiondeclareapp.GrantUriPermission;
+
import java.io.IOException;
+import java.util.List;
/**
* Tests that signature-enforced permissions cannot be accessed by apps signed
@@ -54,6 +58,14 @@
private static final String EXPECTED_MIME_TYPE_AMBIGUOUS = "got/theUnspecifiedMIME";
private static final Uri AMBIGUOUS_URI = Uri.parse("content://ctsambiguousprovider");
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ // Always dispose, usually to clean up from failed tests
+ ReceiveUriActivity.finishCurInstanceSync();
+ }
+
private void assertReadingContentUriNotAllowed(Uri uri, String msg) {
try {
getContext().getContentResolver().query(uri, null, null, null, null);
@@ -423,11 +435,11 @@
synchronized (this) {
mHaveResult = true;
switch (getResultCode()) {
- case 100:
+ case GrantUriPermission.FAILURE:
mGoodResult = true;
mSucceeded = false;
break;
- case 101:
+ case GrantUriPermission.SUCCESS:
mGoodResult = true;
mSucceeded = true;
break;
@@ -491,8 +503,9 @@
service ? ReceiveUriService.class : ReceiveUriActivity.class);
Intent intent = new Intent();
intent.setComponent(GRANT_URI_PERM_COMP);
- intent.putExtra("intent", grantIntent);
- intent.putExtra("service", service);
+ intent.setAction(service ? GrantUriPermission.ACTION_START_SERVICE
+ : GrantUriPermission.ACTION_START_ACTIVITY);
+ intent.putExtra(GrantUriPermission.EXTRA_INTENT, grantIntent);
GrantResultReceiver receiver = new GrantResultReceiver();
getContext().sendOrderedBroadcast(intent, null, receiver, null, 0, null, null);
receiver.assertFailure("Able to grant URI permission to " + grantDataUri + " when should not");
@@ -502,8 +515,9 @@
service ? ReceiveUriService.class : ReceiveUriActivity.class);
intent = new Intent();
intent.setComponent(GRANT_URI_PERM_COMP);
- intent.putExtra("intent", grantIntent);
- intent.putExtra("service", service);
+ intent.setAction(service ? GrantUriPermission.ACTION_START_SERVICE
+ : GrantUriPermission.ACTION_START_ACTIVITY);
+ intent.putExtra(GrantUriPermission.EXTRA_INTENT, grantIntent);
receiver = new GrantResultReceiver();
getContext().sendOrderedBroadcast(intent, null, receiver, null, 0, null, null);
receiver.assertFailure("Able to grant URI permission to " + grantIntent.getClipData()
@@ -578,8 +592,9 @@
service ? ReceiveUriService.class : ReceiveUriActivity.class);
Intent intent = new Intent();
intent.setComponent(GRANT_URI_PERM_COMP);
- intent.putExtra("intent", grantIntent);
- intent.putExtra("service", service);
+ intent.setAction(service ? GrantUriPermission.ACTION_START_SERVICE
+ : GrantUriPermission.ACTION_START_ACTIVITY);
+ intent.putExtra(GrantUriPermission.EXTRA_INTENT, grantIntent);
getContext().sendBroadcast(intent);
}
@@ -843,7 +858,7 @@
doTestGrantActivityUriWritePermission(PRIV_URI_GRANTING, false);
}
- void doTestGrantServiceUriReadPermission(Uri uri, boolean useClip) {
+ private void doTestGrantServiceUriReadPermission(Uri uri, boolean useClip) {
final Uri subUri = Uri.withAppendedPath(uri, "foo");
final Uri subSubUri = Uri.withAppendedPath(subUri, "bar");
final Uri sub2Uri = Uri.withAppendedPath(uri, "yes");
@@ -1207,4 +1222,137 @@
assertEquals(EXPECTED_MIME_TYPE_AMBIGUOUS,
getContext().getContentResolver().getType(AMBIGUOUS_URI_COMPAT));
}
+
+ /**
+ * Validate behavior of persistable permission grants.
+ */
+ public void testGrantPersistableUriPermission() {
+ final ContentResolver resolver = getContext().getContentResolver();
+
+ final Uri target = Uri.withAppendedPath(PERM_URI_GRANTING, "foo");
+ final ClipData clip = makeSingleClipData(target);
+
+ // Make sure we can't see the target
+ assertReadingClipNotAllowed(clip, "reading should have failed");
+ assertWritingClipNotAllowed(clip, "writing should have failed");
+
+ // Make sure we can't take a grant we don't have
+ try {
+ resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ fail("taking read should have failed");
+ } catch (SecurityException expected) {
+ }
+
+ // And since we were just installed, no persisted grants yet
+ assertNoPersistedUriPermission();
+
+ // Now, let's grant ourselves some access
+ ReceiveUriActivity.clearStarted();
+ grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
+ ReceiveUriActivity.waitForStart();
+
+ // We should now have reading access, even before taking the persistable
+ // grant. Persisted grants should still be empty.
+ assertReadingClipAllowed(clip);
+ assertWritingClipNotAllowed(clip, "writing should have failed");
+ assertNoPersistedUriPermission();
+
+ // Take the read grant and verify we have it!
+ long before = System.currentTimeMillis();
+ resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ long after = System.currentTimeMillis();
+ assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
+
+ // Make sure we can't take a grant we don't have
+ try {
+ resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ fail("taking write should have failed");
+ } catch (SecurityException expected) {
+ }
+
+ // Launch again giving ourselves persistable read and write access
+ ReceiveUriActivity.clearNewIntent();
+ grantClipUriPermission(clip, Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+ | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
+ ReceiveUriActivity.waitForNewIntent();
+
+ // Previous persisted grant should be unchanged
+ assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
+
+ // We should have both read and write; read is persisted, and write
+ // isn't persisted yet.
+ assertReadingClipAllowed(clip);
+ assertWritingClipAllowed(clip);
+
+ // Take again, but still only read; should just update timestamp
+ before = System.currentTimeMillis();
+ resolver.takePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ after = System.currentTimeMillis();
+ assertPersistedUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION, before, after);
+
+ // And take yet again, both read and write
+ before = System.currentTimeMillis();
+ resolver.takePersistableUriPermission(target,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ after = System.currentTimeMillis();
+ assertPersistedUriPermission(target,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
+ before, after);
+
+ // Now drop the persisted grant; write first, then read
+ resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ assertPersistedUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, before, after);
+ resolver.releasePersistableUriPermission(target, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+ assertNoPersistedUriPermission();
+
+ // And even though we dropped the persistable grants, our activity is
+ // still running with the global grants (until reboot).
+ assertReadingClipAllowed(clip);
+ assertWritingClipAllowed(clip);
+
+ ReceiveUriActivity.finishCurInstanceSync();
+ }
+
+ private void assertNoPersistedUriPermission() {
+ assertPersistedUriPermission(null, 0, -1, -1);
+ }
+
+ private void assertPersistedUriPermission(Uri uri, int flags, long before, long after) {
+ // Assert local
+ final List<UriPermission> perms = getContext()
+ .getContentResolver().getPersistedUriPermissions();
+ if (uri != null) {
+ assertEquals("expected exactly one permission", 1, perms.size());
+
+ final UriPermission perm = perms.get(0);
+ assertEquals("unexpected uri", uri, perm.getUri());
+
+ final long actual = perm.getPersistedTime();
+ if (before != -1) {
+ assertTrue("found " + actual + " before " + before, actual >= before);
+ }
+ if (after != -1) {
+ assertTrue("found " + actual + " after " + after, actual <= after);
+ }
+
+ final boolean expectedRead = (flags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0;
+ final boolean expectedWrite = (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0;
+ assertEquals("unexpected read status", expectedRead, perm.isReadPermission());
+ assertEquals("unexpected write status", expectedWrite, perm.isWritePermission());
+
+ } else {
+ assertEquals("expected zero permissions", 0, perms.size());
+ }
+
+ // And assert remote
+ Intent intent = new Intent();
+ intent.setComponent(GRANT_URI_PERM_COMP);
+ intent.setAction(GrantUriPermission.ACTION_VERIFY_OUTGOING_PERSISTED);
+ intent.putExtra(GrantUriPermission.EXTRA_URI, uri);
+ GrantResultReceiver receiver = new GrantResultReceiver();
+ getContext().sendOrderedBroadcast(intent, null, receiver, null, 0, null, null);
+ receiver.assertSuccess("unexpected outgoing persisted Uri status");
+ }
}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ReceiveUriActivity.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ReceiveUriActivity.java
index 851d8da..dd9a5c5 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ReceiveUriActivity.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ReceiveUriActivity.java
@@ -32,7 +32,7 @@
private static final Object sLock = new Object();
private static boolean sStarted;
private static boolean sNewIntent;
- private static boolean sDestroyed;
+ private static boolean sDestroyed = true;
private static ReceiveUriActivity sCurInstance;
private static final long TIMEOUT_MILLIS = 30 * SECOND_IN_MILLIS;